﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using Nop.Core;
using Nop.Core.ComponentModel;
using Nop.Core.Data;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Configuration;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.Seo;
using Nop.Core.Domain.Stores;
using Nop.Core.Domain.Tax;
using Nop.Data;
using Nop.Services.Seo;

namespace SpotsHub.Tools.MassUploader
{
    public class DataAdapter
    {
        public class ImportParams
        {
            public ProductGenerator pg;
            public BackgroundWorker progress;
        }

        private IRepository<Product> _productRepository;
        private IRepository<Store> _storeRepository;
        private IRepository<ProductTemplate> _productTemplateRepository;
        private IRepository<Category> _categoryRepository;
        private IRepository<TaxCategory> _taxCategoryRepository;
        private IRepository<UrlRecord> _urlRecordRepository;
        private IRepository<Picture> _pictureRepository;
        private IRepository<ProductAttribute> _productAttributeRepository;
        private IRepository<Setting> _settingRepository;
        private NopObjectContext _dbContext;

        private List<string> reservedUrlSlugs = null;
        private bool convertNonWesternChars;
        private bool allowUnicodeCharsInUrls;
        private static Dictionary<string, string> _seoCharacterTable;

        private static DataAdapter _instance = new DataAdapter();
        public static DataAdapter Instance
        {
            get
            {
                return _instance;
            }
        }

        public bool Connected { get; set; }

        public int MaximumImageSize = 400;
        public long DefaultImageQuality = 100;
        public bool DefaultAllowCustomerReviews = true;
        public bool DefaultPublished = true;
        public bool DefaultIsShippable = true;
        public int DefaultNotifyAdminForQuantityBelow = 1;
        public bool DefaultAllowBackInStockSubscriptions = false;
        public bool DefaultDisplayStockAvailability = true;
        public LowStockActivity DefaultLowStockActivity = LowStockActivity.DisableBuyButton;
        public BackorderMode DefaultBackorderMode = BackorderMode.NoBackorders;
        public ManageInventoryMethod DefaultManageInventoryMethod = ManageInventoryMethod.ManageStock;

        private DataAdapter()
        {
            Connected = false;
        }

        public void ConnectToDatabase()
        {
            var manager = new DataSettingsManagerLocal();
            var settings = manager.LoadSettings();

            _dbContext = new NopObjectContext(settings.DataConnectionString);
            _productRepository = new EfRepository<Product>(_dbContext);
            _storeRepository = new EfRepository<Store>(_dbContext);
            _productTemplateRepository = new EfRepository<ProductTemplate>(_dbContext);
            _categoryRepository = new EfRepository<Category>(_dbContext);
            _taxCategoryRepository = new EfRepository<TaxCategory>(_dbContext);
            _urlRecordRepository = new EfRepository<UrlRecord>(_dbContext);
            _pictureRepository = new EfRepository<Picture>(_dbContext);
            _settingRepository = new EfRepository<Setting>(_dbContext);
            _productAttributeRepository = new EfRepository<ProductAttribute>(_dbContext);

            Connected = true;
        }

        public void Disconnect()
        {
            if (Connected)
            {
                _dbContext.Dispose();
                _dbContext = null;
                Connected = false;
            }
        }

        public IList<Product> GetAllProducts(bool showHidden = false, int storeId = 1, int categoryId = 0)
        {
            var query = from p in _productRepository.Table
                        orderby p.Name
                        where (showHidden || p.Published) &&
                        !p.Deleted &&
                        (storeId == 1 || p.StoreId == storeId) &&
                        (categoryId == 0 || p.ProductCategories.Any(pc => pc.CategoryId == categoryId))
                        select p;
            var products = query.ToList();
            return products;
        }

        public IList<Store> GetAllStores(bool showHidden = false, bool showReserved = false)
        {
            var query = from m in _storeRepository.Table
                        orderby m.DisplayOrder
                        where (showHidden || m.Published) && !m.Deleted && (showReserved || m.Id != Store.AllStoreReservedId)
                        select m;
            var stores = query.ToList();
            return stores;
        }

        public IList<Store> GetStoreByName(string name)
        {
            var stores = GetAllStores(true, false);
            var res = stores.Where(s => s.Name.ToLower().Contains(name.ToLower()));
            return res == null ? null : res.ToList();
        }

        public List<string> GetProductAttributeNames()
        {
            var query = from pa in _productAttributeRepository.Table
                        select pa.Name;
            return query.ToList();
        }

        public void AddProductAttribute(string name, string description)
        {
            var pa = new ProductAttribute()
            {
                Name = name,
                Description = description
            };
            _productAttributeRepository.Insert(pa);
        }

        public void AddProductAttributeValue(int productId, string attributeName, AttributeControlType controlType, bool isRequired, List<ProductVariantAttributeValue> values)
        {
            var productTemplateInGrid =
                _productTemplateRepository.Table.Where(pt => pt.Name == "Variants in Grid").FirstOrDefault();

            var query = from p in _productRepository.Table
                        where p.Id == productId
                        select p;
            var product = query.FirstOrDefault();

            product.ProductTemplateId = productTemplateInGrid.Id;
            
            var att = new ProductVariantAttribute()
            {
                ProductAttribute = _productAttributeRepository.Table.Where(x => x.Name == attributeName).Single(),
                AttributeControlType = controlType,
                IsRequired = isRequired,
            };

            values.ForEach(v => att.ProductVariantAttributeValues.Add(v));
            product.ProductVariants.FirstOrDefault().ProductVariantAttributes.Add(att);

            _productRepository.Update(product);
        }

        public void ImportProducts(object param)
        {
            getSeoSettings();

            if (param == null || !(param is ImportParams))
            {
                return;
            }

            ProductGenerator pg = ((ImportParams)param).pg;
            BackgroundWorker progress = ((ImportParams)param).progress;

            if (pg.ProductsInformation == null)
            {
                return;
            }

            if (pg.PictureFiles == null)
            {
                return;
            }

            //var productTemplateInGrid =
            //    _productTemplateRepository.Table.Where(pt => pt.Name == "Variants in Grid").FirstOrDefault();
            var productTemplateSingleVariant =
                _productTemplateRepository.Table.Where(pt => pt.Name == "Single Product Variant").FirstOrDefault();

            var allProducts = new List<Product>();

            int count = pg.ProductsInformation.Rows.Count;

            Logger.Inst.Add("Starting to upload. {0} products in the queue.", count);

            for (int i = 0; i < count; i++)
            {
                progress.ReportProgress(i);

                var row = pg.ProductsInformation.Rows[i];

                var product = new Product()
                {
                    Name = row["Name"] as string,
                    ShortDescription = row["ShortDescription"] as string,
                    FullDescription = row["FullDescription"] as string,
                    ProductTemplateId = productTemplateSingleVariant.Id,
                    AllowCustomerReviews = DefaultAllowCustomerReviews,
                    StoreId = (int)row["StoreId"],
                    Published = DefaultPublished,
                    CreatedOnUtc = DateTime.UtcNow,
                    UpdatedOnUtc = DateTime.UtcNow
                };
                Logger.Inst.Add("Creating the product '{0}'.", product.Name);

                string tpc = (string)row["TaxCategory"];
                string pc = (string)row["ProductCategory"];
                int taxCategoryId = 0;
                Category category = null;

                Logger.Inst.Add("Looking up the tax category '{0}'...", tpc);
                taxCategoryId = _taxCategoryRepository.Table.Where(tc => tc.Name == tpc).Single().Id;

                Logger.Inst.Add("Looking up the product category '{0}'...", pc);
                category = _categoryRepository.Table.Where(c => c.Name == pc).Single();

                product.ProductVariants.Add(new ProductVariant()
                {
                    Price = (decimal)row["Price"],
                    OldPrice = 0M,
                    IsShipEnabled = DefaultIsShippable,
                    Weight = (decimal)row["Weight"],
                    Length = (decimal)row["Length"],
                    Width = (decimal)row["Width"],
                    Height = (decimal)row["Height"],
                    TaxCategoryId = taxCategoryId,
                    ManageInventoryMethod = ManageInventoryMethod.ManageStock,
                    StockQuantity = (int)row["StockQuantity"],
                    NotifyAdminForQuantityBelow = DefaultNotifyAdminForQuantityBelow,
                    AllowBackInStockSubscriptions = DefaultAllowBackInStockSubscriptions,
                    DisplayStockAvailability = DefaultDisplayStockAvailability,
                    LowStockActivity = DefaultLowStockActivity,
                    BackorderMode = DefaultBackorderMode,
                    OrderMinimumQuantity = 1,
                    OrderMaximumQuantity = (int)row["OrderMaximumQuantity"],
                    Published = true,
                    DisplayOrder = 1,
                    CreatedOnUtc = DateTime.UtcNow,
                    UpdatedOnUtc = DateTime.UtcNow,
                });
                Logger.Inst.Add("Created the product variant for '{0}'...", product.Name);

                product.ProductCategories.Add(new ProductCategory()
                {
                    Category = category,
                    DisplayOrder = 1,
                });
                Logger.Inst.Add("Added the product '{0}' to the category {1}.", product.Name, category.Name);

                var pictures = pg.PictureFiles[(int)row["ID"]];

                for (int j = 1; j <= pictures.Count; j++)
                {
                    product.ProductPictures.Add(new ProductPicture()
                    {
                        Picture = InsertPicture(File.ReadAllBytes(pictures[j - 1]), "image/jpeg", SeoExtensions.GetSeName(product.Name, true, false), true),
                        DisplayOrder = j,
                    });
                    Logger.Inst.Add("Added the picture #{0} for product '{1}' successfully.", j, product.Name);
                }

                Logger.Inst.Add("Adding {0}:{1} to the database.", (int)row["ID"], product.Name);

                _productRepository.Insert(product);

                Logger.Inst.Add("Added {0}:{1} to the database successfully!", (int)row["ID"], product.Name);

                allProducts.Add(product);
            }

            //search engine names
            foreach (var product in allProducts)
            {
                _urlRecordRepository.Insert(new UrlRecord()
                {
                    EntityId = product.Id,
                    EntityName = "Product",
                    LanguageId = 0,
                    Slug = validateSeName(product, "", product.Name, true)
                });
            }

            //TODO: Related products
        }

        private string validateSeName(Product entity, string seName, string name, bool ensureNotEmpty)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            //use name if sename is not specified
            if (String.IsNullOrWhiteSpace(seName) && !String.IsNullOrWhiteSpace(name))
                seName = name;

            //validation
            seName = getSeName(seName);

            //max length
            seName = CommonHelper.EnsureMaximumLength(seName, 400);

            if (String.IsNullOrWhiteSpace(seName))
            {
                if (ensureNotEmpty)
                {
                    //use entity identifier as sename if empty
                    seName = entity.Id.ToString();
                }
                else
                {
                    //return. no need for further processing
                    return seName;
                }
            }

            //ensure this sename is not reserved yet
            string entityName = "Product";
            int i = 2;
            var tempSeName = seName;
            while (true)
            {
                //check whether such slug already exists (and that is not the current product)
                var urlRecord = getBySlug(tempSeName);
                var reserved1 = urlRecord != null && !(urlRecord.EntityId == entity.Id && urlRecord.EntityName.Equals(entityName, StringComparison.InvariantCultureIgnoreCase));
                //and it's not in the list of reserved slugs
                var reserved2 = reservedUrlSlugs.Contains(tempSeName, StringComparer.InvariantCultureIgnoreCase);
                if (!reserved1 && !reserved2)
                    break;

                tempSeName = string.Format("{0}-{1}", seName, i);
                i++;
            }
            seName = tempSeName;

            return seName;
        }

        private void getSeoSettings()
        {
            if (reservedUrlSlugs == null)
            {
                reservedUrlSlugs = new List<string>();

                var query = from r in _settingRepository.Table
                            where r.Name == "seosettings.reservedurlrecordslugs"
                            select r.Value;
                string value = query.FirstOrDefault();

                reservedUrlSlugs = (List<string>)new GenericListTypeConverter<string>().ConvertFrom(null, System.Globalization.CultureInfo.InvariantCulture, value);
            }

            var query1 = from r in _settingRepository.Table
                         where r.Name == "seosettings.allowunicodecharsinurls"
                         select r.Value;
            string value1 = query1.FirstOrDefault();
            allowUnicodeCharsInUrls = Boolean.Parse(value1);

            var query2 = from r in _settingRepository.Table
                         where r.Name == "seosettings.convertnonwesternchars"
                         select r.Value;
            string value2 = query2.FirstOrDefault();
            convertNonWesternChars = Boolean.Parse(value2);
        }

        private string getSeName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return name;
            string okChars = "abcdefghijklmnopqrstuvwxyz1234567890 _-";
            name = name.Trim().ToLowerInvariant();

            if (convertNonWesternChars)
            {
                if (_seoCharacterTable == null)
                    initializeSeoCharacterTable();
            }

            var sb = new StringBuilder();
            foreach (char c in name.ToCharArray())
            {
                string c2 = c.ToString();
                if (convertNonWesternChars)
                {
                    if (_seoCharacterTable.ContainsKey(c2))
                        c2 = _seoCharacterTable[c2];
                }

                if (allowUnicodeCharsInUrls)
                {
                    if (char.IsLetterOrDigit(c) || okChars.Contains(c2))
                        sb.Append(c2);
                }
                else if (okChars.Contains(c2))
                {
                    sb.Append(c2);
                }
            }
            string name2 = sb.ToString();
            name2 = name2.Replace(" ", "-");
            while (name2.Contains("--"))
                name2 = name2.Replace("--", "-");
            while (name2.Contains("__"))
                name2 = name2.Replace("__", "_");
            return name2;
        }

        private static string toUnichar(string hexString)
        {
            string returnChar;
            byte[] b = new byte[2];
            var ue = new UnicodeEncoding();

            // Take hexadecimal as text and make a Unicode char number
            b[0] = Convert.ToByte(hexString.Substring(2, 2), 16);
            b[1] = Convert.ToByte(hexString.Substring(0, 2), 16);
            // Get the character the number represents
            returnChar = ue.GetString(b);
            return returnChar;
        }

        private static void initializeSeoCharacterTable()
        {
            if (_seoCharacterTable == null)
            {
                _seoCharacterTable = new Dictionary<string, string>();
                _seoCharacterTable.Add(toUnichar("0041"), "A");
                _seoCharacterTable.Add(toUnichar("0042"), "B");
                _seoCharacterTable.Add(toUnichar("0043"), "C");
                _seoCharacterTable.Add(toUnichar("0044"), "D");
                _seoCharacterTable.Add(toUnichar("0045"), "E");
                _seoCharacterTable.Add(toUnichar("0046"), "F");
                _seoCharacterTable.Add(toUnichar("0047"), "G");
                _seoCharacterTable.Add(toUnichar("0048"), "H");
                _seoCharacterTable.Add(toUnichar("0049"), "I");
                _seoCharacterTable.Add(toUnichar("004A"), "J");
                _seoCharacterTable.Add(toUnichar("004B"), "K");
                _seoCharacterTable.Add(toUnichar("004C"), "L");
                _seoCharacterTable.Add(toUnichar("004D"), "M");
                _seoCharacterTable.Add(toUnichar("004E"), "N");
                _seoCharacterTable.Add(toUnichar("004F"), "O");
                _seoCharacterTable.Add(toUnichar("0050"), "P");
                _seoCharacterTable.Add(toUnichar("0051"), "Q");
                _seoCharacterTable.Add(toUnichar("0052"), "R");
                _seoCharacterTable.Add(toUnichar("0053"), "S");
                _seoCharacterTable.Add(toUnichar("0054"), "T");
                _seoCharacterTable.Add(toUnichar("0055"), "U");
                _seoCharacterTable.Add(toUnichar("0056"), "V");
                _seoCharacterTable.Add(toUnichar("0057"), "W");
                _seoCharacterTable.Add(toUnichar("0058"), "X");
                _seoCharacterTable.Add(toUnichar("0059"), "Y");
                _seoCharacterTable.Add(toUnichar("005A"), "Z");
                _seoCharacterTable.Add(toUnichar("0061"), "a");
                _seoCharacterTable.Add(toUnichar("0062"), "b");
                _seoCharacterTable.Add(toUnichar("0063"), "c");
                _seoCharacterTable.Add(toUnichar("0064"), "d");
                _seoCharacterTable.Add(toUnichar("0065"), "e");
                _seoCharacterTable.Add(toUnichar("0066"), "f");
                _seoCharacterTable.Add(toUnichar("0067"), "g");
                _seoCharacterTable.Add(toUnichar("0068"), "h");
                _seoCharacterTable.Add(toUnichar("0069"), "i");
                _seoCharacterTable.Add(toUnichar("006A"), "j");
                _seoCharacterTable.Add(toUnichar("006B"), "k");
                _seoCharacterTable.Add(toUnichar("006C"), "l");
                _seoCharacterTable.Add(toUnichar("006D"), "m");
                _seoCharacterTable.Add(toUnichar("006E"), "n");
                _seoCharacterTable.Add(toUnichar("006F"), "o");
                _seoCharacterTable.Add(toUnichar("0070"), "p");
                _seoCharacterTable.Add(toUnichar("0071"), "q");
                _seoCharacterTable.Add(toUnichar("0072"), "r");
                _seoCharacterTable.Add(toUnichar("0073"), "s");
                _seoCharacterTable.Add(toUnichar("0074"), "t");
                _seoCharacterTable.Add(toUnichar("0075"), "u");
                _seoCharacterTable.Add(toUnichar("0076"), "v");
                _seoCharacterTable.Add(toUnichar("0077"), "w");
                _seoCharacterTable.Add(toUnichar("0078"), "x");
                _seoCharacterTable.Add(toUnichar("0079"), "y");
                _seoCharacterTable.Add(toUnichar("007A"), "z");
                _seoCharacterTable.Add(toUnichar("00AA"), "a");    // FEMININE ORDINAL INDICATOR
                _seoCharacterTable.Add(toUnichar("00BA"), "o");	// MASCULINE ORDINAL INDICATOR
                _seoCharacterTable.Add(toUnichar("00C0"), "A");	// LATIN CAPITAL LETTER A WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00C1"), "A");	// LATIN CAPITAL LETTER A WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00C2"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00C3"), "A");	// LATIN CAPITAL LETTER A WITH TILDE
                _seoCharacterTable.Add(toUnichar("00C4"), "A");	// LATIN CAPITAL LETTER A WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00C5"), "A");	// LATIN CAPITAL LETTER A WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("00C6"), "AE");	// LATIN CAPITAL LETTER AE -- no decomposition
                _seoCharacterTable.Add(toUnichar("00C7"), "C");	// LATIN CAPITAL LETTER C WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("00C8"), "E");	// LATIN CAPITAL LETTER E WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00C9"), "E");	// LATIN CAPITAL LETTER E WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00CA"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00CB"), "E");	// LATIN CAPITAL LETTER E WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00CC"), "I");	// LATIN CAPITAL LETTER I WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00CD"), "I");	// LATIN CAPITAL LETTER I WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00CE"), "I");	// LATIN CAPITAL LETTER I WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00CF"), "I");	// LATIN CAPITAL LETTER I WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00D0"), "D");	// LATIN CAPITAL LETTER ETH -- no decomposition  	// Eth [D for Vietnamese]
                _seoCharacterTable.Add(toUnichar("00D1"), "N");	// LATIN CAPITAL LETTER N WITH TILDE
                _seoCharacterTable.Add(toUnichar("00D2"), "O");	// LATIN CAPITAL LETTER O WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00D3"), "O");	// LATIN CAPITAL LETTER O WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00D4"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00D5"), "O");	// LATIN CAPITAL LETTER O WITH TILDE
                _seoCharacterTable.Add(toUnichar("00D6"), "O");	// LATIN CAPITAL LETTER O WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00D8"), "O");	// LATIN CAPITAL LETTER O WITH STROKE -- no decom
                _seoCharacterTable.Add(toUnichar("00D9"), "U");	// LATIN CAPITAL LETTER U WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00DA"), "U");	// LATIN CAPITAL LETTER U WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00DB"), "U");	// LATIN CAPITAL LETTER U WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00DC"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00DD"), "Y");	// LATIN CAPITAL LETTER Y WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00DE"), "Th");	// LATIN CAPITAL LETTER THORN -- no decomposition; // Thorn - Could be nothing other than thorn
                _seoCharacterTable.Add(toUnichar("00DF"), "s");	// LATIN SMALL LETTER SHARP S -- no decomposition
                _seoCharacterTable.Add(toUnichar("00E0"), "a");	// LATIN SMALL LETTER A WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00E1"), "a");	// LATIN SMALL LETTER A WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00E2"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00E3"), "a");	// LATIN SMALL LETTER A WITH TILDE
                _seoCharacterTable.Add(toUnichar("00E4"), "a");	// LATIN SMALL LETTER A WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00E5"), "a");	// LATIN SMALL LETTER A WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("00E6"), "ae");	// LATIN SMALL LETTER AE -- no decomposition
                _seoCharacterTable.Add(toUnichar("00E7"), "c");	// LATIN SMALL LETTER C WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("00E8"), "e");	// LATIN SMALL LETTER E WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00E9"), "e");	// LATIN SMALL LETTER E WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00EA"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00EB"), "e");	// LATIN SMALL LETTER E WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00EC"), "i");	// LATIN SMALL LETTER I WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00ED"), "i");	// LATIN SMALL LETTER I WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00EE"), "i");	// LATIN SMALL LETTER I WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00EF"), "i");	// LATIN SMALL LETTER I WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00F0"), "d");	// LATIN SMALL LETTER ETH -- no decomposition         // small eth, "d" for benefit of Vietnamese
                _seoCharacterTable.Add(toUnichar("00F1"), "n");	// LATIN SMALL LETTER N WITH TILDE
                _seoCharacterTable.Add(toUnichar("00F2"), "o");	// LATIN SMALL LETTER O WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00F3"), "o");	// LATIN SMALL LETTER O WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00F4"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00F5"), "o");	// LATIN SMALL LETTER O WITH TILDE
                _seoCharacterTable.Add(toUnichar("00F6"), "o");	// LATIN SMALL LETTER O WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00F8"), "o");	// LATIN SMALL LETTER O WITH STROKE -- no decompo
                _seoCharacterTable.Add(toUnichar("00F9"), "u");	// LATIN SMALL LETTER U WITH GRAVE
                _seoCharacterTable.Add(toUnichar("00FA"), "u");	// LATIN SMALL LETTER U WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00FB"), "u");	// LATIN SMALL LETTER U WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("00FC"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("00FD"), "y");	// LATIN SMALL LETTER Y WITH ACUTE
                _seoCharacterTable.Add(toUnichar("00FE"), "th");	// LATIN SMALL LETTER THORN -- no decomposition  // Small thorn
                _seoCharacterTable.Add(toUnichar("00FF"), "y");	// LATIN SMALL LETTER Y WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("0100"), "A");	// LATIN CAPITAL LETTER A WITH MACRON
                _seoCharacterTable.Add(toUnichar("0101"), "a");	// LATIN SMALL LETTER A WITH MACRON
                _seoCharacterTable.Add(toUnichar("0102"), "A");	// LATIN CAPITAL LETTER A WITH BREVE
                _seoCharacterTable.Add(toUnichar("0103"), "a");	// LATIN SMALL LETTER A WITH BREVE
                _seoCharacterTable.Add(toUnichar("0104"), "A");	// LATIN CAPITAL LETTER A WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0105"), "a");	// LATIN SMALL LETTER A WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0106"), "C");	// LATIN CAPITAL LETTER C WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0107"), "c");	// LATIN SMALL LETTER C WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0108"), "C");	// LATIN CAPITAL LETTER C WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0109"), "c");	// LATIN SMALL LETTER C WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("010A"), "C");	// LATIN CAPITAL LETTER C WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("010B"), "c");	// LATIN SMALL LETTER C WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("010C"), "C");	// LATIN CAPITAL LETTER C WITH CARON
                _seoCharacterTable.Add(toUnichar("010D"), "c");	// LATIN SMALL LETTER C WITH CARON
                _seoCharacterTable.Add(toUnichar("010E"), "D");	// LATIN CAPITAL LETTER D WITH CARON
                _seoCharacterTable.Add(toUnichar("010F"), "d");	// LATIN SMALL LETTER D WITH CARON
                _seoCharacterTable.Add(toUnichar("0110"), "D");	// LATIN CAPITAL LETTER D WITH STROKE -- no decomposition                     // Capital D with stroke
                _seoCharacterTable.Add(toUnichar("0111"), "d");	// LATIN SMALL LETTER D WITH STROKE -- no decomposition                       // small D with stroke
                _seoCharacterTable.Add(toUnichar("0112"), "E");	// LATIN CAPITAL LETTER E WITH MACRON
                _seoCharacterTable.Add(toUnichar("0113"), "e");	// LATIN SMALL LETTER E WITH MACRON
                _seoCharacterTable.Add(toUnichar("0114"), "E");	// LATIN CAPITAL LETTER E WITH BREVE
                _seoCharacterTable.Add(toUnichar("0115"), "e");	// LATIN SMALL LETTER E WITH BREVE
                _seoCharacterTable.Add(toUnichar("0116"), "E");	// LATIN CAPITAL LETTER E WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0117"), "e");	// LATIN SMALL LETTER E WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0118"), "E");	// LATIN CAPITAL LETTER E WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0119"), "e");	// LATIN SMALL LETTER E WITH OGONEK
                _seoCharacterTable.Add(toUnichar("011A"), "E");	// LATIN CAPITAL LETTER E WITH CARON
                _seoCharacterTable.Add(toUnichar("011B"), "e");	// LATIN SMALL LETTER E WITH CARON
                _seoCharacterTable.Add(toUnichar("011C"), "G");	// LATIN CAPITAL LETTER G WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("011D"), "g");	// LATIN SMALL LETTER G WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("011E"), "G");	// LATIN CAPITAL LETTER G WITH BREVE
                _seoCharacterTable.Add(toUnichar("011F"), "g");	// LATIN SMALL LETTER G WITH BREVE
                _seoCharacterTable.Add(toUnichar("0120"), "G");	// LATIN CAPITAL LETTER G WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0121"), "g");	// LATIN SMALL LETTER G WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0122"), "G");	// LATIN CAPITAL LETTER G WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0123"), "g");	// LATIN SMALL LETTER G WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0124"), "H");	// LATIN CAPITAL LETTER H WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0125"), "h");	// LATIN SMALL LETTER H WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0126"), "H");	// LATIN CAPITAL LETTER H WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0127"), "h");	// LATIN SMALL LETTER H WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0128"), "I");	// LATIN CAPITAL LETTER I WITH TILDE
                _seoCharacterTable.Add(toUnichar("0129"), "i");	// LATIN SMALL LETTER I WITH TILDE
                _seoCharacterTable.Add(toUnichar("012A"), "I");	// LATIN CAPITAL LETTER I WITH MACRON
                _seoCharacterTable.Add(toUnichar("012B"), "i");	// LATIN SMALL LETTER I WITH MACRON
                _seoCharacterTable.Add(toUnichar("012C"), "I");	// LATIN CAPITAL LETTER I WITH BREVE
                _seoCharacterTable.Add(toUnichar("012D"), "i");	// LATIN SMALL LETTER I WITH BREVE
                _seoCharacterTable.Add(toUnichar("012E"), "I");	// LATIN CAPITAL LETTER I WITH OGONEK
                _seoCharacterTable.Add(toUnichar("012F"), "i");	// LATIN SMALL LETTER I WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0130"), "I");	// LATIN CAPITAL LETTER I WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0131"), "i");	// LATIN SMALL LETTER DOTLESS I -- no decomposition
                _seoCharacterTable.Add(toUnichar("0132"), "I");	// LATIN CAPITAL LIGATURE IJ    
                _seoCharacterTable.Add(toUnichar("0133"), "i");	// LATIN SMALL LIGATURE IJ      
                _seoCharacterTable.Add(toUnichar("0134"), "J");	// LATIN CAPITAL LETTER J WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0135"), "j");	// LATIN SMALL LETTER J WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0136"), "K");	// LATIN CAPITAL LETTER K WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0137"), "k");	// LATIN SMALL LETTER K WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0138"), "k");	// LATIN SMALL LETTER KRA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0139"), "L");	// LATIN CAPITAL LETTER L WITH ACUTE
                _seoCharacterTable.Add(toUnichar("013A"), "l");	// LATIN SMALL LETTER L WITH ACUTE
                _seoCharacterTable.Add(toUnichar("013B"), "L");	// LATIN CAPITAL LETTER L WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("013C"), "l");	// LATIN SMALL LETTER L WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("013D"), "L");	// LATIN CAPITAL LETTER L WITH CARON
                _seoCharacterTable.Add(toUnichar("013E"), "l");	// LATIN SMALL LETTER L WITH CARON
                _seoCharacterTable.Add(toUnichar("013F"), "L");	// LATIN CAPITAL LETTER L WITH MIDDLE DOT
                _seoCharacterTable.Add(toUnichar("0140"), "l");	// LATIN SMALL LETTER L WITH MIDDLE DOT
                _seoCharacterTable.Add(toUnichar("0141"), "L");	// LATIN CAPITAL LETTER L WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0142"), "l");	// LATIN SMALL LETTER L WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0143"), "N");	// LATIN CAPITAL LETTER N WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0144"), "n");	// LATIN SMALL LETTER N WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0145"), "N");	// LATIN CAPITAL LETTER N WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0146"), "n");	// LATIN SMALL LETTER N WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0147"), "N");	// LATIN CAPITAL LETTER N WITH CARON
                _seoCharacterTable.Add(toUnichar("0148"), "n");	// LATIN SMALL LETTER N WITH CARON
                _seoCharacterTable.Add(toUnichar("0149"), "'n");	// LATIN SMALL LETTER N PRECEDED BY APOSTROPHE                              ;
                _seoCharacterTable.Add(toUnichar("014A"), "NG");	// LATIN CAPITAL LETTER ENG -- no decomposition                             ;
                _seoCharacterTable.Add(toUnichar("014B"), "ng");	// LATIN SMALL LETTER ENG -- no decomposition                               ;
                _seoCharacterTable.Add(toUnichar("014C"), "O");	// LATIN CAPITAL LETTER O WITH MACRON
                _seoCharacterTable.Add(toUnichar("014D"), "o");	// LATIN SMALL LETTER O WITH MACRON
                _seoCharacterTable.Add(toUnichar("014E"), "O");	// LATIN CAPITAL LETTER O WITH BREVE
                _seoCharacterTable.Add(toUnichar("014F"), "o");	// LATIN SMALL LETTER O WITH BREVE
                _seoCharacterTable.Add(toUnichar("0150"), "O");	// LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
                _seoCharacterTable.Add(toUnichar("0151"), "o");	// LATIN SMALL LETTER O WITH DOUBLE ACUTE
                _seoCharacterTable.Add(toUnichar("0152"), "OE");	// LATIN CAPITAL LIGATURE OE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0153"), "oe");	// LATIN SMALL LIGATURE OE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0154"), "R");	// LATIN CAPITAL LETTER R WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0155"), "r");	// LATIN SMALL LETTER R WITH ACUTE
                _seoCharacterTable.Add(toUnichar("0156"), "R");	// LATIN CAPITAL LETTER R WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0157"), "r");	// LATIN SMALL LETTER R WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0158"), "R");	// LATIN CAPITAL LETTER R WITH CARON
                _seoCharacterTable.Add(toUnichar("0159"), "r");	// LATIN SMALL LETTER R WITH CARON
                _seoCharacterTable.Add(toUnichar("015A"), "S");	// LATIN CAPITAL LETTER S WITH ACUTE
                _seoCharacterTable.Add(toUnichar("015B"), "s");	// LATIN SMALL LETTER S WITH ACUTE
                _seoCharacterTable.Add(toUnichar("015C"), "S");	// LATIN CAPITAL LETTER S WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("015D"), "s");	// LATIN SMALL LETTER S WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("015E"), "S");	// LATIN CAPITAL LETTER S WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("015F"), "s");	// LATIN SMALL LETTER S WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0160"), "S");	// LATIN CAPITAL LETTER S WITH CARON
                _seoCharacterTable.Add(toUnichar("0161"), "s");	// LATIN SMALL LETTER S WITH CARON
                _seoCharacterTable.Add(toUnichar("0162"), "T");	// LATIN CAPITAL LETTER T WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0163"), "t");	// LATIN SMALL LETTER T WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0164"), "T");	// LATIN CAPITAL LETTER T WITH CARON
                _seoCharacterTable.Add(toUnichar("0165"), "t");	// LATIN SMALL LETTER T WITH CARON
                _seoCharacterTable.Add(toUnichar("0166"), "T");	// LATIN CAPITAL LETTER T WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0167"), "t");	// LATIN SMALL LETTER T WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0168"), "U");	// LATIN CAPITAL LETTER U WITH TILDE
                _seoCharacterTable.Add(toUnichar("0169"), "u");	// LATIN SMALL LETTER U WITH TILDE
                _seoCharacterTable.Add(toUnichar("016A"), "U");	// LATIN CAPITAL LETTER U WITH MACRON
                _seoCharacterTable.Add(toUnichar("016B"), "u");	// LATIN SMALL LETTER U WITH MACRON
                _seoCharacterTable.Add(toUnichar("016C"), "U");	// LATIN CAPITAL LETTER U WITH BREVE
                _seoCharacterTable.Add(toUnichar("016D"), "u");	// LATIN SMALL LETTER U WITH BREVE
                _seoCharacterTable.Add(toUnichar("016E"), "U");	// LATIN CAPITAL LETTER U WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("016F"), "u");	// LATIN SMALL LETTER U WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("0170"), "U");	// LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
                _seoCharacterTable.Add(toUnichar("0171"), "u");	// LATIN SMALL LETTER U WITH DOUBLE ACUTE
                _seoCharacterTable.Add(toUnichar("0172"), "U");	// LATIN CAPITAL LETTER U WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0173"), "u");	// LATIN SMALL LETTER U WITH OGONEK
                _seoCharacterTable.Add(toUnichar("0174"), "W");	// LATIN CAPITAL LETTER W WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0175"), "w");	// LATIN SMALL LETTER W WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0176"), "Y");	// LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0177"), "y");	// LATIN SMALL LETTER Y WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("0178"), "Y");	// LATIN CAPITAL LETTER Y WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("0179"), "Z");	// LATIN CAPITAL LETTER Z WITH ACUTE
                _seoCharacterTable.Add(toUnichar("017A"), "z");	// LATIN SMALL LETTER Z WITH ACUTE
                _seoCharacterTable.Add(toUnichar("017B"), "Z");	// LATIN CAPITAL LETTER Z WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("017C"), "z");	// LATIN SMALL LETTER Z WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("017D"), "Z");	// LATIN CAPITAL LETTER Z WITH CARON
                _seoCharacterTable.Add(toUnichar("017E"), "z");	// LATIN SMALL LETTER Z WITH CARON
                _seoCharacterTable.Add(toUnichar("017F"), "s");	// LATIN SMALL LETTER LONG S    
                _seoCharacterTable.Add(toUnichar("0180"), "b");	// LATIN SMALL LETTER B WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0181"), "B");	// LATIN CAPITAL LETTER B WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0182"), "B");	// LATIN CAPITAL LETTER B WITH TOPBAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("0183"), "b");	// LATIN SMALL LETTER B WITH TOPBAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("0184"), "6");	// LATIN CAPITAL LETTER TONE SIX -- no decomposition
                _seoCharacterTable.Add(toUnichar("0185"), "6");	// LATIN SMALL LETTER TONE SIX -- no decomposition
                _seoCharacterTable.Add(toUnichar("0186"), "O");	// LATIN CAPITAL LETTER OPEN O -- no decomposition
                _seoCharacterTable.Add(toUnichar("0187"), "C");	// LATIN CAPITAL LETTER C WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0188"), "c");	// LATIN SMALL LETTER C WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0189"), "D");	// LATIN CAPITAL LETTER AFRICAN D -- no decomposition
                _seoCharacterTable.Add(toUnichar("018A"), "D");	// LATIN CAPITAL LETTER D WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("018B"), "D");	// LATIN CAPITAL LETTER D WITH TOPBAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("018C"), "d");	// LATIN SMALL LETTER D WITH TOPBAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("018D"), "d");	// LATIN SMALL LETTER TURNED DELTA -- no decomposition
                _seoCharacterTable.Add(toUnichar("018E"), "E");	// LATIN CAPITAL LETTER REVERSED E -- no decomposition
                _seoCharacterTable.Add(toUnichar("018F"), "E");	// LATIN CAPITAL LETTER SCHWA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0190"), "E");	// LATIN CAPITAL LETTER OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("0191"), "F");	// LATIN CAPITAL LETTER F WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0192"), "f");	// LATIN SMALL LETTER F WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0193"), "G");	// LATIN CAPITAL LETTER G WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0194"), "G");	// LATIN CAPITAL LETTER GAMMA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0195"), "hv");	// LATIN SMALL LETTER HV -- no decomposition
                _seoCharacterTable.Add(toUnichar("0196"), "I");	// LATIN CAPITAL LETTER IOTA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0197"), "I");	// LATIN CAPITAL LETTER I WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0198"), "K");	// LATIN CAPITAL LETTER K WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0199"), "k");	// LATIN SMALL LETTER K WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("019A"), "l");	// LATIN SMALL LETTER L WITH BAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("019B"), "l");	// LATIN SMALL LETTER LAMBDA WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("019C"), "M");	// LATIN CAPITAL LETTER TURNED M -- no decomposition
                _seoCharacterTable.Add(toUnichar("019D"), "N");	// LATIN CAPITAL LETTER N WITH LEFT HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("019E"), "n");	// LATIN SMALL LETTER N WITH LONG RIGHT LEG -- no decomposition
                _seoCharacterTable.Add(toUnichar("019F"), "O");	// LATIN CAPITAL LETTER O WITH MIDDLE TILDE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A0"), "O");	// LATIN CAPITAL LETTER O WITH HORN
                _seoCharacterTable.Add(toUnichar("01A1"), "o");	// LATIN SMALL LETTER O WITH HORN
                _seoCharacterTable.Add(toUnichar("01A2"), "OI");	// LATIN CAPITAL LETTER OI -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A3"), "oi");	// LATIN SMALL LETTER OI -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A4"), "P");	// LATIN CAPITAL LETTER P WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A5"), "p");	// LATIN SMALL LETTER P WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A6"), "YR");	// LATIN LETTER YR -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A7"), "2");	// LATIN CAPITAL LETTER TONE TWO -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A8"), "2");	// LATIN SMALL LETTER TONE TWO -- no decomposition
                _seoCharacterTable.Add(toUnichar("01A9"), "S");	// LATIN CAPITAL LETTER ESH -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AA"), "s");	// LATIN LETTER REVERSED ESH LOOP -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AB"), "t");	// LATIN SMALL LETTER T WITH PALATAL HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AC"), "T");	// LATIN CAPITAL LETTER T WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AD"), "t");	// LATIN SMALL LETTER T WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AE"), "T");	// LATIN CAPITAL LETTER T WITH RETROFLEX HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01AF"), "U");	// LATIN CAPITAL LETTER U WITH HORN
                _seoCharacterTable.Add(toUnichar("01B0"), "u");	// LATIN SMALL LETTER U WITH HORN
                _seoCharacterTable.Add(toUnichar("01B1"), "u");	// LATIN CAPITAL LETTER UPSILON -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B2"), "V");	// LATIN CAPITAL LETTER V WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B3"), "Y");	// LATIN CAPITAL LETTER Y WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B4"), "y");	// LATIN SMALL LETTER Y WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B5"), "Z");	// LATIN CAPITAL LETTER Z WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B6"), "z");	// LATIN SMALL LETTER Z WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B7"), "Z");	// LATIN CAPITAL LETTER EZH -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B8"), "Z");	// LATIN CAPITAL LETTER EZH REVERSED -- no decomposition
                _seoCharacterTable.Add(toUnichar("01B9"), "Z");	// LATIN SMALL LETTER EZH REVERSED -- no decomposition
                _seoCharacterTable.Add(toUnichar("01BA"), "z");	// LATIN SMALL LETTER EZH WITH TAIL -- no decomposition
                _seoCharacterTable.Add(toUnichar("01BB"), "2");	// LATIN LETTER TWO WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01BC"), "5");	// LATIN CAPITAL LETTER TONE FIVE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01BD"), "5");	// LATIN SMALL LETTER TONE FIVE -- no decomposition
                //_seoCharacterTable.Add(ToUnichar("01BE"), "´");	// LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01BF"), "w");	// LATIN LETTER WYNN -- no decomposition
                _seoCharacterTable.Add(toUnichar("01C0"), "!");	// LATIN LETTER DENTAL CLICK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01C1"), "!");	// LATIN LETTER LATERAL CLICK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01C2"), "!");	// LATIN LETTER ALVEOLAR CLICK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01C3"), "!");	// LATIN LETTER RETROFLEX CLICK -- no decomposition
                _seoCharacterTable.Add(toUnichar("01C4"), "DZ");	// LATIN CAPITAL LETTER DZ WITH CARON
                _seoCharacterTable.Add(toUnichar("01C5"), "DZ");	// LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
                _seoCharacterTable.Add(toUnichar("01C6"), "d");	// LATIN SMALL LETTER DZ WITH CARON
                _seoCharacterTable.Add(toUnichar("01C7"), "Lj");	// LATIN CAPITAL LETTER LJ
                _seoCharacterTable.Add(toUnichar("01C8"), "Lj");	// LATIN CAPITAL LETTER L WITH SMALL LETTER J
                _seoCharacterTable.Add(toUnichar("01C9"), "lj");	// LATIN SMALL LETTER LJ
                _seoCharacterTable.Add(toUnichar("01CA"), "NJ");	// LATIN CAPITAL LETTER NJ
                _seoCharacterTable.Add(toUnichar("01CB"), "NJ");	// LATIN CAPITAL LETTER N WITH SMALL LETTER J
                _seoCharacterTable.Add(toUnichar("01CC"), "nj");	// LATIN SMALL LETTER NJ
                _seoCharacterTable.Add(toUnichar("01CD"), "A");	// LATIN CAPITAL LETTER A WITH CARON
                _seoCharacterTable.Add(toUnichar("01CE"), "a");	// LATIN SMALL LETTER A WITH CARON
                _seoCharacterTable.Add(toUnichar("01CF"), "I");	// LATIN CAPITAL LETTER I WITH CARON
                _seoCharacterTable.Add(toUnichar("01D0"), "i");	// LATIN SMALL LETTER I WITH CARON
                _seoCharacterTable.Add(toUnichar("01D1"), "O");	// LATIN CAPITAL LETTER O WITH CARON
                _seoCharacterTable.Add(toUnichar("01D2"), "o");	// LATIN SMALL LETTER O WITH CARON
                _seoCharacterTable.Add(toUnichar("01D3"), "U");	// LATIN CAPITAL LETTER U WITH CARON
                _seoCharacterTable.Add(toUnichar("01D4"), "u");	// LATIN SMALL LETTER U WITH CARON
                _seoCharacterTable.Add(toUnichar("01D5"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("01D6"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("01D7"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
                _seoCharacterTable.Add(toUnichar("01D8"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
                _seoCharacterTable.Add(toUnichar("01D9"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
                _seoCharacterTable.Add(toUnichar("01DA"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS AND CARON
                _seoCharacterTable.Add(toUnichar("01DB"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
                _seoCharacterTable.Add(toUnichar("01DC"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
                _seoCharacterTable.Add(toUnichar("01DD"), "e");	// LATIN SMALL LETTER TURNED E -- no decomposition
                _seoCharacterTable.Add(toUnichar("01DE"), "A");	// LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("01DF"), "a");	// LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("01E0"), "A");	// LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
                _seoCharacterTable.Add(toUnichar("01E1"), "a");	// LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
                _seoCharacterTable.Add(toUnichar("01E2"), "AE");	// LATIN CAPITAL LETTER AE WITH MACRON
                _seoCharacterTable.Add(toUnichar("01E3"), "ae");	// LATIN SMALL LETTER AE WITH MACRON
                _seoCharacterTable.Add(toUnichar("01E4"), "G");	// LATIN CAPITAL LETTER G WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01E5"), "g");	// LATIN SMALL LETTER G WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("01E6"), "G");	// LATIN CAPITAL LETTER G WITH CARON
                _seoCharacterTable.Add(toUnichar("01E7"), "g");	// LATIN SMALL LETTER G WITH CARON
                _seoCharacterTable.Add(toUnichar("01E8"), "K");	// LATIN CAPITAL LETTER K WITH CARON
                _seoCharacterTable.Add(toUnichar("01E9"), "k");	// LATIN SMALL LETTER K WITH CARON
                _seoCharacterTable.Add(toUnichar("01EA"), "O");	// LATIN CAPITAL LETTER O WITH OGONEK
                _seoCharacterTable.Add(toUnichar("01EB"), "o");	// LATIN SMALL LETTER O WITH OGONEK
                _seoCharacterTable.Add(toUnichar("01EC"), "O");	// LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
                _seoCharacterTable.Add(toUnichar("01ED"), "o");	// LATIN SMALL LETTER O WITH OGONEK AND MACRON
                _seoCharacterTable.Add(toUnichar("01EE"), "Z");	// LATIN CAPITAL LETTER EZH WITH CARON
                _seoCharacterTable.Add(toUnichar("01EF"), "Z");	// LATIN SMALL LETTER EZH WITH CARON
                _seoCharacterTable.Add(toUnichar("01F0"), "j");	// LATIN SMALL LETTER J WITH CARON
                _seoCharacterTable.Add(toUnichar("01F1"), "DZ");	// LATIN CAPITAL LETTER DZ
                _seoCharacterTable.Add(toUnichar("01F2"), "DZ");	// LATIN CAPITAL LETTER D WITH SMALL LETTER Z
                _seoCharacterTable.Add(toUnichar("01F3"), "dz");	// LATIN SMALL LETTER DZ
                _seoCharacterTable.Add(toUnichar("01F4"), "G");	// LATIN CAPITAL LETTER G WITH ACUTE
                _seoCharacterTable.Add(toUnichar("01F5"), "g");	// LATIN SMALL LETTER G WITH ACUTE
                _seoCharacterTable.Add(toUnichar("01F6"), "hv");	// LATIN CAPITAL LETTER HWAIR -- no decomposition
                _seoCharacterTable.Add(toUnichar("01F7"), "w");	// LATIN CAPITAL LETTER WYNN -- no decomposition
                _seoCharacterTable.Add(toUnichar("01F8"), "N");	// LATIN CAPITAL LETTER N WITH GRAVE
                _seoCharacterTable.Add(toUnichar("01F9"), "n");	// LATIN SMALL LETTER N WITH GRAVE
                _seoCharacterTable.Add(toUnichar("01FA"), "A");	// LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
                _seoCharacterTable.Add(toUnichar("01FB"), "a");	// LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
                _seoCharacterTable.Add(toUnichar("01FC"), "AE");	// LATIN CAPITAL LETTER AE WITH ACUTE
                _seoCharacterTable.Add(toUnichar("01FD"), "ae");	// LATIN SMALL LETTER AE WITH ACUTE
                _seoCharacterTable.Add(toUnichar("01FE"), "O");	// LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
                _seoCharacterTable.Add(toUnichar("01FF"), "o");	// LATIN SMALL LETTER O WITH STROKE AND ACUTE
                _seoCharacterTable.Add(toUnichar("0200"), "A");	// LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0201"), "a");	// LATIN SMALL LETTER A WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0202"), "A");	// LATIN CAPITAL LETTER A WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0203"), "a");	// LATIN SMALL LETTER A WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0204"), "E");	// LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0205"), "e");	// LATIN SMALL LETTER E WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0206"), "E");	// LATIN CAPITAL LETTER E WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0207"), "e");	// LATIN SMALL LETTER E WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0208"), "I");	// LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0209"), "i");	// LATIN SMALL LETTER I WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("020A"), "I");	// LATIN CAPITAL LETTER I WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("020B"), "i");	// LATIN SMALL LETTER I WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("020C"), "O");	// LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("020D"), "o");	// LATIN SMALL LETTER O WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("020E"), "O");	// LATIN CAPITAL LETTER O WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("020F"), "o");	// LATIN SMALL LETTER O WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0210"), "R");	// LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0211"), "r");	// LATIN SMALL LETTER R WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0212"), "R");	// LATIN CAPITAL LETTER R WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0213"), "r");	// LATIN SMALL LETTER R WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0214"), "U");	// LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0215"), "u");	// LATIN SMALL LETTER U WITH DOUBLE GRAVE
                _seoCharacterTable.Add(toUnichar("0216"), "U");	// LATIN CAPITAL LETTER U WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0217"), "u");	// LATIN SMALL LETTER U WITH INVERTED BREVE
                _seoCharacterTable.Add(toUnichar("0218"), "S");	// LATIN CAPITAL LETTER S WITH COMMA BELOW
                _seoCharacterTable.Add(toUnichar("0219"), "s");	// LATIN SMALL LETTER S WITH COMMA BELOW
                _seoCharacterTable.Add(toUnichar("021A"), "T");	// LATIN CAPITAL LETTER T WITH COMMA BELOW
                _seoCharacterTable.Add(toUnichar("021B"), "t");	// LATIN SMALL LETTER T WITH COMMA BELOW
                _seoCharacterTable.Add(toUnichar("021C"), "Z");	// LATIN CAPITAL LETTER YOGH -- no decomposition
                _seoCharacterTable.Add(toUnichar("021D"), "z");	// LATIN SMALL LETTER YOGH -- no decomposition
                _seoCharacterTable.Add(toUnichar("021E"), "H");	// LATIN CAPITAL LETTER H WITH CARON
                _seoCharacterTable.Add(toUnichar("021F"), "h");	// LATIN SMALL LETTER H WITH CARON
                _seoCharacterTable.Add(toUnichar("0220"), "N");	// LATIN CAPITAL LETTER N WITH LONG RIGHT LEG -- no decomposition
                _seoCharacterTable.Add(toUnichar("0221"), "d");	// LATIN SMALL LETTER D WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0222"), "OU");	// LATIN CAPITAL LETTER OU -- no decomposition
                _seoCharacterTable.Add(toUnichar("0223"), "ou");	// LATIN SMALL LETTER OU -- no decomposition
                _seoCharacterTable.Add(toUnichar("0224"), "Z");	// LATIN CAPITAL LETTER Z WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0225"), "z");	// LATIN SMALL LETTER Z WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0226"), "A");	// LATIN CAPITAL LETTER A WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0227"), "a");	// LATIN SMALL LETTER A WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0228"), "E");	// LATIN CAPITAL LETTER E WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("0229"), "e");	// LATIN SMALL LETTER E WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("022A"), "O");	// LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("022B"), "o");	// LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
                _seoCharacterTable.Add(toUnichar("022C"), "O");	// LATIN CAPITAL LETTER O WITH TILDE AND MACRON
                _seoCharacterTable.Add(toUnichar("022D"), "o");	// LATIN SMALL LETTER O WITH TILDE AND MACRON
                _seoCharacterTable.Add(toUnichar("022E"), "O");	// LATIN CAPITAL LETTER O WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("022F"), "o");	// LATIN SMALL LETTER O WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("0230"), "O");	// LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
                _seoCharacterTable.Add(toUnichar("0231"), "o");	// LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
                _seoCharacterTable.Add(toUnichar("0232"), "Y");	// LATIN CAPITAL LETTER Y WITH MACRON
                _seoCharacterTable.Add(toUnichar("0233"), "y");	// LATIN SMALL LETTER Y WITH MACRON
                _seoCharacterTable.Add(toUnichar("0234"), "l");	// LATIN SMALL LETTER L WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0235"), "n");	// LATIN SMALL LETTER N WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0236"), "t");	// LATIN SMALL LETTER T WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0250"), "a");	// LATIN SMALL LETTER TURNED A -- no decomposition
                _seoCharacterTable.Add(toUnichar("0251"), "a");	// LATIN SMALL LETTER ALPHA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0252"), "a");	// LATIN SMALL LETTER TURNED ALPHA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0253"), "b");	// LATIN SMALL LETTER B WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0254"), "o");	// LATIN SMALL LETTER OPEN O -- no decomposition
                _seoCharacterTable.Add(toUnichar("0255"), "c");	// LATIN SMALL LETTER C WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0256"), "d");	// LATIN SMALL LETTER D WITH TAIL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0257"), "d");	// LATIN SMALL LETTER D WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0258"), "e");	// LATIN SMALL LETTER REVERSED E -- no decomposition
                _seoCharacterTable.Add(toUnichar("0259"), "e");	// LATIN SMALL LETTER SCHWA -- no decomposition
                _seoCharacterTable.Add(toUnichar("025A"), "e");	// LATIN SMALL LETTER SCHWA WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("025B"), "e");	// LATIN SMALL LETTER OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("025C"), "e");	// LATIN SMALL LETTER REVERSED OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("025D"), "e");	// LATIN SMALL LETTER REVERSED OPEN E WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("025E"), "e");	// LATIN SMALL LETTER CLOSED REVERSED OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("025F"), "j");	// LATIN SMALL LETTER DOTLESS J WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0260"), "g");	// LATIN SMALL LETTER G WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0261"), "g");	// LATIN SMALL LETTER SCRIPT G -- no decomposition
                _seoCharacterTable.Add(toUnichar("0262"), "G");	// LATIN LETTER SMALL CAPITAL G -- no decomposition
                _seoCharacterTable.Add(toUnichar("0263"), "g");	// LATIN SMALL LETTER GAMMA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0264"), "y");	// LATIN SMALL LETTER RAMS HORN -- no decomposition
                _seoCharacterTable.Add(toUnichar("0265"), "h");	// LATIN SMALL LETTER TURNED H -- no decomposition
                _seoCharacterTable.Add(toUnichar("0266"), "h");	// LATIN SMALL LETTER H WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0267"), "h");	// LATIN SMALL LETTER HENG WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0268"), "i");	// LATIN SMALL LETTER I WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0269"), "i");	// LATIN SMALL LETTER IOTA -- no decomposition
                _seoCharacterTable.Add(toUnichar("026A"), "I");	// LATIN LETTER SMALL CAPITAL I -- no decomposition
                _seoCharacterTable.Add(toUnichar("026B"), "l");	// LATIN SMALL LETTER L WITH MIDDLE TILDE -- no decomposition
                _seoCharacterTable.Add(toUnichar("026C"), "l");	// LATIN SMALL LETTER L WITH BELT -- no decomposition
                _seoCharacterTable.Add(toUnichar("026D"), "l");	// LATIN SMALL LETTER L WITH RETROFLEX HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("026E"), "lz");	// LATIN SMALL LETTER LEZH -- no decomposition
                _seoCharacterTable.Add(toUnichar("026F"), "m");	// LATIN SMALL LETTER TURNED M -- no decomposition
                _seoCharacterTable.Add(toUnichar("0270"), "m");	// LATIN SMALL LETTER TURNED M WITH LONG LEG -- no decomposition
                _seoCharacterTable.Add(toUnichar("0271"), "m");	// LATIN SMALL LETTER M WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0272"), "n");	// LATIN SMALL LETTER N WITH LEFT HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0273"), "n");	// LATIN SMALL LETTER N WITH RETROFLEX HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0274"), "N");	// LATIN LETTER SMALL CAPITAL N -- no decomposition
                _seoCharacterTable.Add(toUnichar("0275"), "o");	// LATIN SMALL LETTER BARRED O -- no decomposition
                _seoCharacterTable.Add(toUnichar("0276"), "OE");	// LATIN LETTER SMALL CAPITAL OE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0277"), "o");	// LATIN SMALL LETTER CLOSED OMEGA -- no decomposition
                _seoCharacterTable.Add(toUnichar("0278"), "ph");	// LATIN SMALL LETTER PHI -- no decomposition
                _seoCharacterTable.Add(toUnichar("0279"), "r");	// LATIN SMALL LETTER TURNED R -- no decomposition
                _seoCharacterTable.Add(toUnichar("027A"), "r");	// LATIN SMALL LETTER TURNED R WITH LONG LEG -- no decomposition
                _seoCharacterTable.Add(toUnichar("027B"), "r");	// LATIN SMALL LETTER TURNED R WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("027C"), "r");	// LATIN SMALL LETTER R WITH LONG LEG -- no decomposition
                _seoCharacterTable.Add(toUnichar("027D"), "r");	// LATIN SMALL LETTER R WITH TAIL -- no decomposition
                _seoCharacterTable.Add(toUnichar("027E"), "r");	// LATIN SMALL LETTER R WITH FISHHOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("027F"), "r");	// LATIN SMALL LETTER REVERSED R WITH FISHHOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0280"), "R");	// LATIN LETTER SMALL CAPITAL R -- no decomposition
                _seoCharacterTable.Add(toUnichar("0281"), "r");	// LATIN LETTER SMALL CAPITAL INVERTED R -- no decomposition
                _seoCharacterTable.Add(toUnichar("0282"), "s");	// LATIN SMALL LETTER S WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0283"), "s");	// LATIN SMALL LETTER ESH -- no decomposition
                _seoCharacterTable.Add(toUnichar("0284"), "j");	// LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0285"), "s");	// LATIN SMALL LETTER SQUAT REVERSED ESH -- no decomposition
                _seoCharacterTable.Add(toUnichar("0286"), "s");	// LATIN SMALL LETTER ESH WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0287"), "y");	// LATIN SMALL LETTER TURNED T -- no decomposition
                _seoCharacterTable.Add(toUnichar("0288"), "t");	// LATIN SMALL LETTER T WITH RETROFLEX HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0289"), "u");	// LATIN SMALL LETTER U BAR -- no decomposition
                _seoCharacterTable.Add(toUnichar("028A"), "u");	// LATIN SMALL LETTER UPSILON -- no decomposition
                _seoCharacterTable.Add(toUnichar("028B"), "u");	// LATIN SMALL LETTER V WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("028C"), "v");	// LATIN SMALL LETTER TURNED V -- no decomposition
                _seoCharacterTable.Add(toUnichar("028D"), "w");	// LATIN SMALL LETTER TURNED W -- no decomposition
                _seoCharacterTable.Add(toUnichar("028E"), "y");	// LATIN SMALL LETTER TURNED Y -- no decomposition
                _seoCharacterTable.Add(toUnichar("028F"), "Y");	// LATIN LETTER SMALL CAPITAL Y -- no decomposition
                _seoCharacterTable.Add(toUnichar("0290"), "z");	// LATIN SMALL LETTER Z WITH RETROFLEX HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0291"), "z");	// LATIN SMALL LETTER Z WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0292"), "z");	// LATIN SMALL LETTER EZH -- no decomposition
                _seoCharacterTable.Add(toUnichar("0293"), "z");	// LATIN SMALL LETTER EZH WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("0294"), "'");	// LATIN LETTER GLOTTAL STOP -- no decomposition
                _seoCharacterTable.Add(toUnichar("0295"), "'");	// LATIN LETTER PHARYNGEAL VOICED FRICATIVE -- no decomposition
                _seoCharacterTable.Add(toUnichar("0296"), "'");	// LATIN LETTER INVERTED GLOTTAL STOP -- no decomposition
                _seoCharacterTable.Add(toUnichar("0297"), "C");	// LATIN LETTER STRETCHED C -- no decomposition
                //_seoCharacterTable.Add(ToUnichar("0298"), "O˜");	// LATIN LETTER BILABIAL CLICK -- no decomposition
                _seoCharacterTable.Add(toUnichar("0299"), "B");	// LATIN LETTER SMALL CAPITAL B -- no decomposition
                _seoCharacterTable.Add(toUnichar("029A"), "e");	// LATIN SMALL LETTER CLOSED OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("029B"), "G");	// LATIN LETTER SMALL CAPITAL G WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("029C"), "H");	// LATIN LETTER SMALL CAPITAL H -- no decomposition
                _seoCharacterTable.Add(toUnichar("029D"), "j");	// LATIN SMALL LETTER J WITH CROSSED-TAIL -- no decomposition
                _seoCharacterTable.Add(toUnichar("029E"), "k");	// LATIN SMALL LETTER TURNED K -- no decomposition
                _seoCharacterTable.Add(toUnichar("029F"), "L");	// LATIN LETTER SMALL CAPITAL L -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A0"), "q");	// LATIN SMALL LETTER Q WITH HOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A1"), "'");	// LATIN LETTER GLOTTAL STOP WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A2"), "'");	// LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A3"), "dz");	// LATIN SMALL LETTER DZ DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A4"), "dz");	// LATIN SMALL LETTER DEZH DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A5"), "dz");	// LATIN SMALL LETTER DZ DIGRAPH WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A6"), "ts");	// LATIN SMALL LETTER TS DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A7"), "ts");	// LATIN SMALL LETTER TESH DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A8"), ""); // LATIN SMALL LETTER TC DIGRAPH WITH CURL -- no decomposition
                _seoCharacterTable.Add(toUnichar("02A9"), "fn");	// LATIN SMALL LETTER FENG DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AA"), "ls");	// LATIN SMALL LETTER LS DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AB"), "lz");	// LATIN SMALL LETTER LZ DIGRAPH -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AC"), "w");	// LATIN LETTER BILABIAL PERCUSSIVE -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AD"), "t");	// LATIN LETTER BIDENTAL PERCUSSIVE -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AE"), "h");	// LATIN SMALL LETTER TURNED H WITH FISHHOOK -- no decomposition
                _seoCharacterTable.Add(toUnichar("02AF"), "h");	// LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL -- no decomposition
                _seoCharacterTable.Add(toUnichar("02B0"), "h");	// MODIFIER LETTER SMALL H
                _seoCharacterTable.Add(toUnichar("02B1"), "h");	// MODIFIER LETTER SMALL H WITH HOOK
                _seoCharacterTable.Add(toUnichar("02B2"), "j");	// MODIFIER LETTER SMALL J
                _seoCharacterTable.Add(toUnichar("02B3"), "r");	// MODIFIER LETTER SMALL R
                _seoCharacterTable.Add(toUnichar("02B4"), "r");	// MODIFIER LETTER SMALL TURNED R
                _seoCharacterTable.Add(toUnichar("02B5"), "r");	// MODIFIER LETTER SMALL TURNED R WITH HOOK
                _seoCharacterTable.Add(toUnichar("02B6"), "R");	// MODIFIER LETTER SMALL CAPITAL INVERTED R
                _seoCharacterTable.Add(toUnichar("02B7"), "w");	// MODIFIER LETTER SMALL W
                _seoCharacterTable.Add(toUnichar("02B8"), "y");	// MODIFIER LETTER SMALL Y
                _seoCharacterTable.Add(toUnichar("02E1"), "l");	// MODIFIER LETTER SMALL L
                _seoCharacterTable.Add(toUnichar("02E2"), "s");	// MODIFIER LETTER SMALL S
                _seoCharacterTable.Add(toUnichar("02E3"), "x");	// MODIFIER LETTER SMALL X
                _seoCharacterTable.Add(toUnichar("02E4"), "'");	// MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
                _seoCharacterTable.Add(toUnichar("1D00"), "A");	// LATIN LETTER SMALL CAPITAL A -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D01"), "AE");	// LATIN LETTER SMALL CAPITAL AE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D02"), "ae");	// LATIN SMALL LETTER TURNED AE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D03"), "B");	// LATIN LETTER SMALL CAPITAL BARRED B -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D04"), "C");	// LATIN LETTER SMALL CAPITAL C -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D05"), "D");	// LATIN LETTER SMALL CAPITAL D -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D06"), "TH");	// LATIN LETTER SMALL CAPITAL ETH -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D07"), "E");	// LATIN LETTER SMALL CAPITAL E -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D08"), "e");	// LATIN SMALL LETTER TURNED OPEN E -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D09"), "i");	// LATIN SMALL LETTER TURNED I -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0A"), "J");	// LATIN LETTER SMALL CAPITAL J -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0B"), "K");	// LATIN LETTER SMALL CAPITAL K -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0C"), "L");	// LATIN LETTER SMALL CAPITAL L WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0D"), "M");	// LATIN LETTER SMALL CAPITAL M -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0E"), "N");	// LATIN LETTER SMALL CAPITAL REVERSED N -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D0F"), "O");	// LATIN LETTER SMALL CAPITAL O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D10"), "O");	// LATIN LETTER SMALL CAPITAL OPEN O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D11"), "o");	// LATIN SMALL LETTER SIDEWAYS O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D12"), "o");	// LATIN SMALL LETTER SIDEWAYS OPEN O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D13"), "o");	// LATIN SMALL LETTER SIDEWAYS O WITH STROKE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D14"), "oe");	// LATIN SMALL LETTER TURNED OE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D15"), "ou");	// LATIN LETTER SMALL CAPITAL OU -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D16"), "o");	// LATIN SMALL LETTER TOP HALF O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D17"), "o");	// LATIN SMALL LETTER BOTTOM HALF O -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D18"), "P");	// LATIN LETTER SMALL CAPITAL P -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D19"), "R");	// LATIN LETTER SMALL CAPITAL REVERSED R -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1A"), "R");	// LATIN LETTER SMALL CAPITAL TURNED R -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1B"), "T");	// LATIN LETTER SMALL CAPITAL T -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1C"), "U");	// LATIN LETTER SMALL CAPITAL U -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1D"), "u");	// LATIN SMALL LETTER SIDEWAYS U -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1E"), "u");	// LATIN SMALL LETTER SIDEWAYS DIAERESIZED U -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D1F"), "m");	// LATIN SMALL LETTER SIDEWAYS TURNED M -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D20"), "V");	// LATIN LETTER SMALL CAPITAL V -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D21"), "W");	// LATIN LETTER SMALL CAPITAL W -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D22"), "Z");	// LATIN LETTER SMALL CAPITAL Z -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D23"), "EZH");	// LATIN LETTER SMALL CAPITAL EZH -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D24"), "'");	// LATIN LETTER VOICED LARYNGEAL SPIRANT -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D25"), "L");	// LATIN LETTER AIN -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D2C"), "A");	// MODIFIER LETTER CAPITAL A
                _seoCharacterTable.Add(toUnichar("1D2D"), "AE");	// MODIFIER LETTER CAPITAL AE
                _seoCharacterTable.Add(toUnichar("1D2E"), "B");	// MODIFIER LETTER CAPITAL B
                _seoCharacterTable.Add(toUnichar("1D2F"), "B");	// MODIFIER LETTER CAPITAL BARRED B -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D30"), "D");	// MODIFIER LETTER CAPITAL D
                _seoCharacterTable.Add(toUnichar("1D31"), "E");	// MODIFIER LETTER CAPITAL E
                _seoCharacterTable.Add(toUnichar("1D32"), "E");	// MODIFIER LETTER CAPITAL REVERSED E
                _seoCharacterTable.Add(toUnichar("1D33"), "G");	// MODIFIER LETTER CAPITAL G
                _seoCharacterTable.Add(toUnichar("1D34"), "H");	// MODIFIER LETTER CAPITAL H
                _seoCharacterTable.Add(toUnichar("1D35"), "I");	// MODIFIER LETTER CAPITAL I
                _seoCharacterTable.Add(toUnichar("1D36"), "J");	// MODIFIER LETTER CAPITAL J
                _seoCharacterTable.Add(toUnichar("1D37"), "K");	// MODIFIER LETTER CAPITAL K
                _seoCharacterTable.Add(toUnichar("1D38"), "L");	// MODIFIER LETTER CAPITAL L
                _seoCharacterTable.Add(toUnichar("1D39"), "M");	// MODIFIER LETTER CAPITAL M
                _seoCharacterTable.Add(toUnichar("1D3A"), "N");	// MODIFIER LETTER CAPITAL N
                _seoCharacterTable.Add(toUnichar("1D3B"), "N");	// MODIFIER LETTER CAPITAL REVERSED N -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D3C"), "O");	// MODIFIER LETTER CAPITAL O
                _seoCharacterTable.Add(toUnichar("1D3D"), "OU");	// MODIFIER LETTER CAPITAL OU
                _seoCharacterTable.Add(toUnichar("1D3E"), "P");	// MODIFIER LETTER CAPITAL P
                _seoCharacterTable.Add(toUnichar("1D3F"), "R");	// MODIFIER LETTER CAPITAL R
                _seoCharacterTable.Add(toUnichar("1D40"), "T");	// MODIFIER LETTER CAPITAL T
                _seoCharacterTable.Add(toUnichar("1D41"), "U");	// MODIFIER LETTER CAPITAL U
                _seoCharacterTable.Add(toUnichar("1D42"), "W");	// MODIFIER LETTER CAPITAL W
                _seoCharacterTable.Add(toUnichar("1D43"), "a");	// MODIFIER LETTER SMALL A
                _seoCharacterTable.Add(toUnichar("1D44"), "a");	// MODIFIER LETTER SMALL TURNED A
                _seoCharacterTable.Add(toUnichar("1D46"), "ae");	// MODIFIER LETTER SMALL TURNED AE
                _seoCharacterTable.Add(toUnichar("1D47"), "b");    // MODIFIER LETTER SMALL B
                _seoCharacterTable.Add(toUnichar("1D48"), "d");    // MODIFIER LETTER SMALL D
                _seoCharacterTable.Add(toUnichar("1D49"), "e");    // MODIFIER LETTER SMALL E
                _seoCharacterTable.Add(toUnichar("1D4A"), "e");    // MODIFIER LETTER SMALL SCHWA
                _seoCharacterTable.Add(toUnichar("1D4B"), "e");    // MODIFIER LETTER SMALL OPEN E
                _seoCharacterTable.Add(toUnichar("1D4C"), "e");    // MODIFIER LETTER SMALL TURNED OPEN E
                _seoCharacterTable.Add(toUnichar("1D4D"), "g");    // MODIFIER LETTER SMALL G
                _seoCharacterTable.Add(toUnichar("1D4E"), "i");    // MODIFIER LETTER SMALL TURNED I -- no decomposition
                _seoCharacterTable.Add(toUnichar("1D4F"), "k");    // MODIFIER LETTER SMALL K
                _seoCharacterTable.Add(toUnichar("1D50"), "m");	// MODIFIER LETTER SMALL M
                _seoCharacterTable.Add(toUnichar("1D51"), "g");	// MODIFIER LETTER SMALL ENG
                _seoCharacterTable.Add(toUnichar("1D52"), "o");	// MODIFIER LETTER SMALL O
                _seoCharacterTable.Add(toUnichar("1D53"), "o");	// MODIFIER LETTER SMALL OPEN O
                _seoCharacterTable.Add(toUnichar("1D54"), "o");	// MODIFIER LETTER SMALL TOP HALF O
                _seoCharacterTable.Add(toUnichar("1D55"), "o");	// MODIFIER LETTER SMALL BOTTOM HALF O
                _seoCharacterTable.Add(toUnichar("1D56"), "p");	// MODIFIER LETTER SMALL P
                _seoCharacterTable.Add(toUnichar("1D57"), "t");	// MODIFIER LETTER SMALL T
                _seoCharacterTable.Add(toUnichar("1D58"), "u");	// MODIFIER LETTER SMALL U
                _seoCharacterTable.Add(toUnichar("1D59"), "u");	// MODIFIER LETTER SMALL SIDEWAYS U
                _seoCharacterTable.Add(toUnichar("1D5A"), "m");	// MODIFIER LETTER SMALL TURNED M
                _seoCharacterTable.Add(toUnichar("1D5B"), "v");	// MODIFIER LETTER SMALL V
                _seoCharacterTable.Add(toUnichar("1D62"), "i");	// LATIN SUBSCRIPT SMALL LETTER I
                _seoCharacterTable.Add(toUnichar("1D63"), "r");	// LATIN SUBSCRIPT SMALL LETTER R
                _seoCharacterTable.Add(toUnichar("1D64"), "u");	// LATIN SUBSCRIPT SMALL LETTER U
                _seoCharacterTable.Add(toUnichar("1D65"), "v");	// LATIN SUBSCRIPT SMALL LETTER V
                _seoCharacterTable.Add(toUnichar("1D6B"), "ue");	// LATIN SMALL LETTER UE -- no decomposition
                _seoCharacterTable.Add(toUnichar("1E00"), "A");	// LATIN CAPITAL LETTER A WITH RING BELOW
                _seoCharacterTable.Add(toUnichar("1E01"), "a");	// LATIN SMALL LETTER A WITH RING BELOW
                _seoCharacterTable.Add(toUnichar("1E02"), "B");	// LATIN CAPITAL LETTER B WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E03"), "b");	// LATIN SMALL LETTER B WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E04"), "B");	// LATIN CAPITAL LETTER B WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E05"), "b");	// LATIN SMALL LETTER B WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E06"), "B");	// LATIN CAPITAL LETTER B WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E07"), "b");	// LATIN SMALL LETTER B WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E08"), "C");	// LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E09"), "c");	// LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E0A"), "D");	// LATIN CAPITAL LETTER D WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E0B"), "d");	// LATIN SMALL LETTER D WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E0C"), "D");	// LATIN CAPITAL LETTER D WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E0D"), "d");	// LATIN SMALL LETTER D WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E0E"), "D");	// LATIN CAPITAL LETTER D WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E0F"), "d");	// LATIN SMALL LETTER D WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E10"), "D");	// LATIN CAPITAL LETTER D WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("1E11"), "d");	// LATIN SMALL LETTER D WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("1E12"), "D");	// LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E13"), "d");	// LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E14"), "E");	// LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
                _seoCharacterTable.Add(toUnichar("1E15"), "e");	// LATIN SMALL LETTER E WITH MACRON AND GRAVE
                _seoCharacterTable.Add(toUnichar("1E16"), "E");	// LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E17"), "e");	// LATIN SMALL LETTER E WITH MACRON AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E18"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E19"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E1A"), "E");	// LATIN CAPITAL LETTER E WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E1B"), "e");	// LATIN SMALL LETTER E WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E1C"), "E");	// LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
                _seoCharacterTable.Add(toUnichar("1E1D"), "e");	// LATIN SMALL LETTER E WITH CEDILLA AND BREVE
                _seoCharacterTable.Add(toUnichar("1E1E"), "F");	// LATIN CAPITAL LETTER F WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E1F"), "f");	// LATIN SMALL LETTER F WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E20"), "G");	// LATIN CAPITAL LETTER G WITH MACRON
                _seoCharacterTable.Add(toUnichar("1E21"), "g");	// LATIN SMALL LETTER G WITH MACRON
                _seoCharacterTable.Add(toUnichar("1E22"), "H");	// LATIN CAPITAL LETTER H WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E23"), "h");	// LATIN SMALL LETTER H WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E24"), "H");	// LATIN CAPITAL LETTER H WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E25"), "h");	// LATIN SMALL LETTER H WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E26"), "H");	// LATIN CAPITAL LETTER H WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E27"), "h");	// LATIN SMALL LETTER H WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E28"), "H");	// LATIN CAPITAL LETTER H WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("1E29"), "h");	// LATIN SMALL LETTER H WITH CEDILLA
                _seoCharacterTable.Add(toUnichar("1E2A"), "H");	// LATIN CAPITAL LETTER H WITH BREVE BELOW
                _seoCharacterTable.Add(toUnichar("1E2B"), "h");	// LATIN SMALL LETTER H WITH BREVE BELOW
                _seoCharacterTable.Add(toUnichar("1E2C"), "I");	// LATIN CAPITAL LETTER I WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E2D"), "i");	// LATIN SMALL LETTER I WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E2E"), "I");	// LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E2F"), "i");	// LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E30"), "K");	// LATIN CAPITAL LETTER K WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E31"), "k");	// LATIN SMALL LETTER K WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E32"), "K");	// LATIN CAPITAL LETTER K WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E33"), "k");	// LATIN SMALL LETTER K WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E34"), "K");	// LATIN CAPITAL LETTER K WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E35"), "k");	// LATIN SMALL LETTER K WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E36"), "L");	// LATIN CAPITAL LETTER L WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E37"), "l");	// LATIN SMALL LETTER L WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E38"), "L");	// LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
                _seoCharacterTable.Add(toUnichar("1E39"), "l");	// LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
                _seoCharacterTable.Add(toUnichar("1E3A"), "L");	// LATIN CAPITAL LETTER L WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E3B"), "l");	// LATIN SMALL LETTER L WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E3C"), "L");	// LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E3D"), "l");	// LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E3E"), "M");	// LATIN CAPITAL LETTER M WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E3F"), "m");	// LATIN SMALL LETTER M WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E40"), "M");	// LATIN CAPITAL LETTER M WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E41"), "m");	// LATIN SMALL LETTER M WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E42"), "M");	// LATIN CAPITAL LETTER M WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E43"), "m");	// LATIN SMALL LETTER M WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E44"), "N");	// LATIN CAPITAL LETTER N WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E45"), "n");	// LATIN SMALL LETTER N WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E46"), "N");	// LATIN CAPITAL LETTER N WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E47"), "n");	// LATIN SMALL LETTER N WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E48"), "N");	// LATIN CAPITAL LETTER N WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E49"), "n");	// LATIN SMALL LETTER N WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E4A"), "N");	// LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E4B"), "n");	// LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E4C"), "O");	// LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E4D"), "o");	// LATIN SMALL LETTER O WITH TILDE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E4E"), "O");	// LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E4F"), "o");	// LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E50"), "O");	// LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
                _seoCharacterTable.Add(toUnichar("1E51"), "o");	// LATIN SMALL LETTER O WITH MACRON AND GRAVE
                _seoCharacterTable.Add(toUnichar("1E52"), "O");	// LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E53"), "o");	// LATIN SMALL LETTER O WITH MACRON AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E54"), "P");	// LATIN CAPITAL LETTER P WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E55"), "p");	// LATIN SMALL LETTER P WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E56"), "P");	// LATIN CAPITAL LETTER P WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E57"), "p");	// LATIN SMALL LETTER P WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E58"), "R");	// LATIN CAPITAL LETTER R WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E59"), "r");	// LATIN SMALL LETTER R WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E5A"), "R");	// LATIN CAPITAL LETTER R WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E5B"), "r");	// LATIN SMALL LETTER R WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E5C"), "R");	// LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
                _seoCharacterTable.Add(toUnichar("1E5D"), "r");	// LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
                _seoCharacterTable.Add(toUnichar("1E5E"), "R");	// LATIN CAPITAL LETTER R WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E5F"), "r");	// LATIN SMALL LETTER R WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E60"), "S");	// LATIN CAPITAL LETTER S WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E61"), "s");	// LATIN SMALL LETTER S WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E62"), "S");	// LATIN CAPITAL LETTER S WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E63"), "s");	// LATIN SMALL LETTER S WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E64"), "S");	// LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E65"), "s");	// LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E66"), "S");	// LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E67"), "s");	// LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E68"), "S");	// LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E69"), "s");	// LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E6A"), "T");	// LATIN CAPITAL LETTER T WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E6B"), "t");	// LATIN SMALL LETTER T WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E6C"), "T");	// LATIN CAPITAL LETTER T WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E6D"), "t");	// LATIN SMALL LETTER T WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E6E"), "T");	// LATIN CAPITAL LETTER T WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E6F"), "t");	// LATIN SMALL LETTER T WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E70"), "T");	// LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E71"), "t");	// LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E72"), "U");	// LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
                _seoCharacterTable.Add(toUnichar("1E73"), "u");	// LATIN SMALL LETTER U WITH DIAERESIS BELOW
                _seoCharacterTable.Add(toUnichar("1E74"), "U");	// LATIN CAPITAL LETTER U WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E75"), "u");	// LATIN SMALL LETTER U WITH TILDE BELOW
                _seoCharacterTable.Add(toUnichar("1E76"), "U");	// LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E77"), "u");	// LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
                _seoCharacterTable.Add(toUnichar("1E78"), "U");	// LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E79"), "u");	// LATIN SMALL LETTER U WITH TILDE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1E7A"), "U");	// LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E7B"), "u");	// LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E7C"), "V");	// LATIN CAPITAL LETTER V WITH TILDE
                _seoCharacterTable.Add(toUnichar("1E7D"), "v");	// LATIN SMALL LETTER V WITH TILDE
                _seoCharacterTable.Add(toUnichar("1E7E"), "V");	// LATIN CAPITAL LETTER V WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E7F"), "v");	// LATIN SMALL LETTER V WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E80"), "W");	// LATIN CAPITAL LETTER W WITH GRAVE
                _seoCharacterTable.Add(toUnichar("1E81"), "w");	// LATIN SMALL LETTER W WITH GRAVE
                _seoCharacterTable.Add(toUnichar("1E82"), "W");	// LATIN CAPITAL LETTER W WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E83"), "w");	// LATIN SMALL LETTER W WITH ACUTE
                _seoCharacterTable.Add(toUnichar("1E84"), "W");	// LATIN CAPITAL LETTER W WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E85"), "w");	// LATIN SMALL LETTER W WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E86"), "W");	// LATIN CAPITAL LETTER W WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E87"), "w");	// LATIN SMALL LETTER W WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E88"), "W");	// LATIN CAPITAL LETTER W WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E89"), "w");	// LATIN SMALL LETTER W WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E8A"), "X");	// LATIN CAPITAL LETTER X WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E8B"), "x");	// LATIN SMALL LETTER X WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E8C"), "X");	// LATIN CAPITAL LETTER X WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E8D"), "x");	// LATIN SMALL LETTER X WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E8E"), "Y");	// LATIN CAPITAL LETTER Y WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E8F"), "y");	// LATIN SMALL LETTER Y WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1E90"), "Z");	// LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("1E91"), "z");	// LATIN SMALL LETTER Z WITH CIRCUMFLEX
                _seoCharacterTable.Add(toUnichar("1E92"), "Z");	// LATIN CAPITAL LETTER Z WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E93"), "z");	// LATIN SMALL LETTER Z WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1E94"), "Z");	// LATIN CAPITAL LETTER Z WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E95"), "z");	// LATIN SMALL LETTER Z WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E96"), "h");	// LATIN SMALL LETTER H WITH LINE BELOW
                _seoCharacterTable.Add(toUnichar("1E97"), "t");	// LATIN SMALL LETTER T WITH DIAERESIS
                _seoCharacterTable.Add(toUnichar("1E98"), "w");	// LATIN SMALL LETTER W WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("1E99"), "y");	// LATIN SMALL LETTER Y WITH RING ABOVE
                _seoCharacterTable.Add(toUnichar("1E9A"), "a");	// LATIN SMALL LETTER A WITH RIGHT HALF RING
                _seoCharacterTable.Add(toUnichar("1E9B"), "s");	// LATIN SMALL LETTER LONG S WITH DOT ABOVE
                _seoCharacterTable.Add(toUnichar("1EA0"), "A");	// LATIN CAPITAL LETTER A WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EA1"), "a");	// LATIN SMALL LETTER A WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EA2"), "A");	// LATIN CAPITAL LETTER A WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EA3"), "a");	// LATIN SMALL LETTER A WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EA4"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EA5"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EA6"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EA7"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EA8"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EA9"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EAA"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1EAB"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1EAC"), "A");	// LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EAD"), "a");	// LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EAE"), "A");	// LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EAF"), "a");	// LATIN SMALL LETTER A WITH BREVE AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EB0"), "A");	// LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EB1"), "a");	// LATIN SMALL LETTER A WITH BREVE AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EB2"), "A");	// LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EB3"), "a");	// LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EB4"), "A");	// LATIN CAPITAL LETTER A WITH BREVE AND TILDE
                _seoCharacterTable.Add(toUnichar("1EB5"), "a");	// LATIN SMALL LETTER A WITH BREVE AND TILDE
                _seoCharacterTable.Add(toUnichar("1EB6"), "A");	// LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EB7"), "a");	// LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EB8"), "E");	// LATIN CAPITAL LETTER E WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EB9"), "e");	// LATIN SMALL LETTER E WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EBA"), "E");	// LATIN CAPITAL LETTER E WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EBB"), "e");	// LATIN SMALL LETTER E WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EBC"), "E");	// LATIN CAPITAL LETTER E WITH TILDE
                _seoCharacterTable.Add(toUnichar("1EBD"), "e");	// LATIN SMALL LETTER E WITH TILDE
                _seoCharacterTable.Add(toUnichar("1EBE"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EBF"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EC0"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EC1"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EC2"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EC3"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EC4"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1EC5"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1EC6"), "E");	// LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EC7"), "e");	// LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EC8"), "I");	// LATIN CAPITAL LETTER I WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EC9"), "i");	// LATIN SMALL LETTER I WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1ECA"), "I");	// LATIN CAPITAL LETTER I WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1ECB"), "i");	// LATIN SMALL LETTER I WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1ECC"), "O");	// LATIN CAPITAL LETTER O WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1ECD"), "o");	// LATIN SMALL LETTER O WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1ECE"), "O");	// LATIN CAPITAL LETTER O WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1ECF"), "o");	// LATIN SMALL LETTER O WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1ED0"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1ED1"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
                _seoCharacterTable.Add(toUnichar("1ED2"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1ED3"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
                _seoCharacterTable.Add(toUnichar("1ED4"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1ED5"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1ED6"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1ED7"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
                _seoCharacterTable.Add(toUnichar("1ED8"), "O");	// LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1ED9"), "o");	// LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EDA"), "O");	// LATIN CAPITAL LETTER O WITH HORN AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EDB"), "o");	// LATIN SMALL LETTER O WITH HORN AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EDC"), "O");	// LATIN CAPITAL LETTER O WITH HORN AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EDD"), "o");	// LATIN SMALL LETTER O WITH HORN AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EDE"), "O");	// LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EDF"), "o");	// LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EE0"), "O");	// LATIN CAPITAL LETTER O WITH HORN AND TILDE
                _seoCharacterTable.Add(toUnichar("1EE1"), "o");	// LATIN SMALL LETTER O WITH HORN AND TILDE
                _seoCharacterTable.Add(toUnichar("1EE2"), "O");	// LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EE3"), "o");	// LATIN SMALL LETTER O WITH HORN AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EE4"), "U");	// LATIN CAPITAL LETTER U WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EE5"), "u");	// LATIN SMALL LETTER U WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EE6"), "U");	// LATIN CAPITAL LETTER U WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EE7"), "u");	// LATIN SMALL LETTER U WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EE8"), "U");	// LATIN CAPITAL LETTER U WITH HORN AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EE9"), "u");	// LATIN SMALL LETTER U WITH HORN AND ACUTE
                _seoCharacterTable.Add(toUnichar("1EEA"), "U");	// LATIN CAPITAL LETTER U WITH HORN AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EEB"), "u");	// LATIN SMALL LETTER U WITH HORN AND GRAVE
                _seoCharacterTable.Add(toUnichar("1EEC"), "U");	// LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EED"), "u");	// LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EEE"), "U");	// LATIN CAPITAL LETTER U WITH HORN AND TILDE
                _seoCharacterTable.Add(toUnichar("1EEF"), "u");	// LATIN SMALL LETTER U WITH HORN AND TILDE
                _seoCharacterTable.Add(toUnichar("1EF0"), "U");	// LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EF1"), "u");	// LATIN SMALL LETTER U WITH HORN AND DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EF2"), "Y");	// LATIN CAPITAL LETTER Y WITH GRAVE
                _seoCharacterTable.Add(toUnichar("1EF3"), "y");	// LATIN SMALL LETTER Y WITH GRAVE
                _seoCharacterTable.Add(toUnichar("1EF4"), "Y");	// LATIN CAPITAL LETTER Y WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EF5"), "y");	// LATIN SMALL LETTER Y WITH DOT BELOW
                _seoCharacterTable.Add(toUnichar("1EF6"), "Y");	// LATIN CAPITAL LETTER Y WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EF7"), "y");	// LATIN SMALL LETTER Y WITH HOOK ABOVE
                _seoCharacterTable.Add(toUnichar("1EF8"), "Y");	// LATIN CAPITAL LETTER Y WITH TILDE
                _seoCharacterTable.Add(toUnichar("1EF9"), "y");	// LATIN SMALL LETTER Y WITH TILDE
                _seoCharacterTable.Add(toUnichar("2071"), "i");	// SUPERSCRIPT LATIN SMALL LETTER I
                _seoCharacterTable.Add(toUnichar("207F"), "n");	// SUPERSCRIPT LATIN SMALL LETTER N
                _seoCharacterTable.Add(toUnichar("212A"), "K");	// KELVIN SIGN
                _seoCharacterTable.Add(toUnichar("212B"), "A");	// ANGSTROM SIGN
                _seoCharacterTable.Add(toUnichar("212C"), "B");	// SCRIPT CAPITAL B
                _seoCharacterTable.Add(toUnichar("212D"), "C");	// BLACK-LETTER CAPITAL C
                _seoCharacterTable.Add(toUnichar("212F"), "e");	// SCRIPT SMALL E
                _seoCharacterTable.Add(toUnichar("2130"), "E");	// SCRIPT CAPITAL E
                _seoCharacterTable.Add(toUnichar("2131"), "F");	// SCRIPT CAPITAL F
                _seoCharacterTable.Add(toUnichar("2132"), "F");	// TURNED CAPITAL F -- no decomposition
                _seoCharacterTable.Add(toUnichar("2133"), "M");	// SCRIPT CAPITAL M
                _seoCharacterTable.Add(toUnichar("2134"), "0");	// SCRIPT SMALL O
                _seoCharacterTable.Add(toUnichar("213A"), "0");	// ROTATED CAPITAL Q -- no decomposition
                _seoCharacterTable.Add(toUnichar("2141"), "G");	// TURNED SANS-SERIF CAPITAL G -- no decomposition
                _seoCharacterTable.Add(toUnichar("2142"), "L");	// TURNED SANS-SERIF CAPITAL L -- no decomposition
                _seoCharacterTable.Add(toUnichar("2143"), "L");	// REVERSED SANS-SERIF CAPITAL L -- no decomposition
                _seoCharacterTable.Add(toUnichar("2144"), "Y");	// TURNED SANS-SERIF CAPITAL Y -- no decomposition
                _seoCharacterTable.Add(toUnichar("2145"), "D");	// DOUBLE-STRUCK ITALIC CAPITAL D
                _seoCharacterTable.Add(toUnichar("2146"), "d");	// DOUBLE-STRUCK ITALIC SMALL D
                _seoCharacterTable.Add(toUnichar("2147"), "e");	// DOUBLE-STRUCK ITALIC SMALL E
                _seoCharacterTable.Add(toUnichar("2148"), "i");	// DOUBLE-STRUCK ITALIC SMALL I
                _seoCharacterTable.Add(toUnichar("2149"), "j");	// DOUBLE-STRUCK ITALIC SMALL J
                _seoCharacterTable.Add(toUnichar("FB00"), "ff");	// LATIN SMALL LIGATURE FF
                _seoCharacterTable.Add(toUnichar("FB01"), "fi");	// LATIN SMALL LIGATURE FI
                _seoCharacterTable.Add(toUnichar("FB02"), "fl");	// LATIN SMALL LIGATURE FL
                _seoCharacterTable.Add(toUnichar("FB03"), "ffi");	// LATIN SMALL LIGATURE FFI
                _seoCharacterTable.Add(toUnichar("FB04"), "ffl");	// LATIN SMALL LIGATURE FFL
                _seoCharacterTable.Add(toUnichar("FB05"), "st");	// LATIN SMALL LIGATURE LONG S T
                _seoCharacterTable.Add(toUnichar("FB06"), "st");	// LATIN SMALL LIGATURE ST
                _seoCharacterTable.Add(toUnichar("FF21"), "A");	// FULLWIDTH LATIN CAPITAL LETTER B
                _seoCharacterTable.Add(toUnichar("FF22"), "B");	// FULLWIDTH LATIN CAPITAL LETTER B
                _seoCharacterTable.Add(toUnichar("FF23"), "C");	// FULLWIDTH LATIN CAPITAL LETTER C
                _seoCharacterTable.Add(toUnichar("FF24"), "D");	// FULLWIDTH LATIN CAPITAL LETTER D
                _seoCharacterTable.Add(toUnichar("FF25"), "E");	// FULLWIDTH LATIN CAPITAL LETTER E
                _seoCharacterTable.Add(toUnichar("FF26"), "F");	// FULLWIDTH LATIN CAPITAL LETTER F
                _seoCharacterTable.Add(toUnichar("FF27"), "G");	// FULLWIDTH LATIN CAPITAL LETTER G
                _seoCharacterTable.Add(toUnichar("FF28"), "H");	// FULLWIDTH LATIN CAPITAL LETTER H
                _seoCharacterTable.Add(toUnichar("FF29"), "I");	// FULLWIDTH LATIN CAPITAL LETTER I
                _seoCharacterTable.Add(toUnichar("FF2A"), "J");	// FULLWIDTH LATIN CAPITAL LETTER J
                _seoCharacterTable.Add(toUnichar("FF2B"), "K");	// FULLWIDTH LATIN CAPITAL LETTER K
                _seoCharacterTable.Add(toUnichar("FF2C"), "L");	// FULLWIDTH LATIN CAPITAL LETTER L
                _seoCharacterTable.Add(toUnichar("FF2D"), "M");	// FULLWIDTH LATIN CAPITAL LETTER M
                _seoCharacterTable.Add(toUnichar("FF2E"), "N");	// FULLWIDTH LATIN CAPITAL LETTER N
                _seoCharacterTable.Add(toUnichar("FF2F"), "O");	// FULLWIDTH LATIN CAPITAL LETTER O
                _seoCharacterTable.Add(toUnichar("FF30"), "P");	// FULLWIDTH LATIN CAPITAL LETTER P
                _seoCharacterTable.Add(toUnichar("FF31"), "Q");	// FULLWIDTH LATIN CAPITAL LETTER Q
                _seoCharacterTable.Add(toUnichar("FF32"), "R");	// FULLWIDTH LATIN CAPITAL LETTER R
                _seoCharacterTable.Add(toUnichar("FF33"), "S");	// FULLWIDTH LATIN CAPITAL LETTER S
                _seoCharacterTable.Add(toUnichar("FF34"), "T");	// FULLWIDTH LATIN CAPITAL LETTER T
                _seoCharacterTable.Add(toUnichar("FF35"), "U");	// FULLWIDTH LATIN CAPITAL LETTER U
                _seoCharacterTable.Add(toUnichar("FF36"), "V");	// FULLWIDTH LATIN CAPITAL LETTER V
                _seoCharacterTable.Add(toUnichar("FF37"), "W");	// FULLWIDTH LATIN CAPITAL LETTER W
                _seoCharacterTable.Add(toUnichar("FF38"), "X");	// FULLWIDTH LATIN CAPITAL LETTER X
                _seoCharacterTable.Add(toUnichar("FF39"), "Y");	// FULLWIDTH LATIN CAPITAL LETTER Y
                _seoCharacterTable.Add(toUnichar("FF3A"), "Z");	// FULLWIDTH LATIN CAPITAL LETTER Z
                _seoCharacterTable.Add(toUnichar("FF41"), "a");	// FULLWIDTH LATIN SMALL LETTER A
                _seoCharacterTable.Add(toUnichar("FF42"), "b");	// FULLWIDTH LATIN SMALL LETTER B
                _seoCharacterTable.Add(toUnichar("FF43"), "c");	// FULLWIDTH LATIN SMALL LETTER C
                _seoCharacterTable.Add(toUnichar("FF44"), "d");	// FULLWIDTH LATIN SMALL LETTER D
                _seoCharacterTable.Add(toUnichar("FF45"), "e");	// FULLWIDTH LATIN SMALL LETTER E
                _seoCharacterTable.Add(toUnichar("FF46"), "f");	// FULLWIDTH LATIN SMALL LETTER F
                _seoCharacterTable.Add(toUnichar("FF47"), "g");	// FULLWIDTH LATIN SMALL LETTER G
                _seoCharacterTable.Add(toUnichar("FF48"), "h");	// FULLWIDTH LATIN SMALL LETTER H
                _seoCharacterTable.Add(toUnichar("FF49"), "i");	// FULLWIDTH LATIN SMALL LETTER I
                _seoCharacterTable.Add(toUnichar("FF4A"), "j");	// FULLWIDTH LATIN SMALL LETTER J
                _seoCharacterTable.Add(toUnichar("FF4B"), "k");	// FULLWIDTH LATIN SMALL LETTER K
                _seoCharacterTable.Add(toUnichar("FF4C"), "l");	// FULLWIDTH LATIN SMALL LETTER L
                _seoCharacterTable.Add(toUnichar("FF4D"), "m");	// FULLWIDTH LATIN SMALL LETTER M
                _seoCharacterTable.Add(toUnichar("FF4E"), "n");	// FULLWIDTH LATIN SMALL LETTER N
                _seoCharacterTable.Add(toUnichar("FF4F"), "o");	// FULLWIDTH LATIN SMALL LETTER O
                _seoCharacterTable.Add(toUnichar("FF50"), "p");	// FULLWIDTH LATIN SMALL LETTER P
                _seoCharacterTable.Add(toUnichar("FF51"), "q");	// FULLWIDTH LATIN SMALL LETTER Q
                _seoCharacterTable.Add(toUnichar("FF52"), "r");	// FULLWIDTH LATIN SMALL LETTER R
                _seoCharacterTable.Add(toUnichar("FF53"), "s");	// FULLWIDTH LATIN SMALL LETTER S
                _seoCharacterTable.Add(toUnichar("FF54"), "t");	// FULLWIDTH LATIN SMALL LETTER T
                _seoCharacterTable.Add(toUnichar("FF55"), "u");	// FULLWIDTH LATIN SMALL LETTER U
                _seoCharacterTable.Add(toUnichar("FF56"), "v");	// FULLWIDTH LATIN SMALL LETTER V
                _seoCharacterTable.Add(toUnichar("FF57"), "w");	// FULLWIDTH LATIN SMALL LETTER W
                _seoCharacterTable.Add(toUnichar("FF58"), "x");	// FULLWIDTH LATIN SMALL LETTER X
                _seoCharacterTable.Add(toUnichar("FF59"), "y");	// FULLWIDTH LATIN SMALL LETTER Y
                _seoCharacterTable.Add(toUnichar("FF5A"), "z");	// FULLWIDTH LATIN SMALL LETTER Z
            }

        }

        private UrlRecord getBySlug(string slug)
        {
            if (String.IsNullOrEmpty(slug))
                return null;

            var query = from ur in _urlRecordRepository.Table
                        where ur.Slug == slug
                        select ur;
            var urlRecord = query.FirstOrDefault();
            return urlRecord;
        }

        public virtual Picture InsertPicture(
            byte[] pictureBinary,
            string mimeType,
            string seoFilename,
            bool isNew,
            bool validateBinary = true)
        {
            mimeType = CommonHelper.EnsureNotNull(mimeType);
            mimeType = CommonHelper.EnsureMaximumLength(mimeType, 20);

            seoFilename = CommonHelper.EnsureMaximumLength(seoFilename, 100);

            if (validateBinary)
                pictureBinary = validatePicture(pictureBinary, mimeType);

            var picture = new Picture()
            {
                //PictureBinary = this.StoreInDb ? pictureBinary : new byte[0],
                PictureBinary = pictureBinary,
                MimeType = mimeType,
                SeoFilename = seoFilename,
                IsNew = isNew,
            };
            _pictureRepository.Insert(picture);

            //if (!this.StoreInDb)
            //    SavePictureInFile(picture.Id, pictureBinary, mimeType);

            //event notification
            //_eventPublisher.EntityInserted(picture);

            return picture;
        }

        private byte[] validatePicture(byte[] pictureBinary, string mimeType)
        {
            using (var stream1 = new MemoryStream(pictureBinary))
            {
                using (var b = new Bitmap(stream1))
                {
                    var maxSize = MaximumImageSize;
                    if ((b.Height <= maxSize) && (b.Width <= maxSize))
                        return pictureBinary;

                    var newSize = calculateDimensions(b.Size, maxSize);
                    using (var newBitMap = new Bitmap(newSize.Width, newSize.Height))
                    {
                        using (var g = Graphics.FromImage(newBitMap))
                        {
                            g.SmoothingMode = SmoothingMode.HighQuality;
                            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            g.DrawImage(b, 0, 0, newSize.Width, newSize.Height);

                            using (var stream2 = new MemoryStream())
                            {
                                var ep = new EncoderParameters();
                                ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, DefaultImageQuality);
                                ImageCodecInfo ici = getImageCodecInfoFromMimeType(mimeType);
                                if (ici == null)
                                    ici = getImageCodecInfoFromMimeType("image/jpeg");
                                newBitMap.Save(stream2, ici, ep);
                                return stream2.GetBuffer();
                            }
                        }
                    }
                }
            }
        }

        private Size calculateDimensions(Size originalSize, int targetSize)
        {
            var newSize = new Size();
            if (originalSize.Height > originalSize.Width) // portrait 
            {
                newSize.Width = (int)(originalSize.Width * (float)(targetSize / (float)originalSize.Height));
                newSize.Height = targetSize;
            }
            else // landscape or square
            {
                newSize.Height = (int)(originalSize.Height * (float)(targetSize / (float)originalSize.Width));
                newSize.Width = targetSize;
            }
            return newSize;
        }

        private ImageCodecInfo getImageCodecInfoFromMimeType(string mimeType)
        {
            var info = ImageCodecInfo.GetImageEncoders();
            foreach (var ici in info)
                if (ici.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))
                    return ici;
            return null;
        }
    }

    public class DataSettingsManagerLocal
    {
        protected const char separator = ':';
        protected const string filename = "Settings.enc";

        protected virtual DataSettings ParseSettings(string text)
        {
            var shellSettings = new DataSettings();
            if (String.IsNullOrEmpty(text))
                return shellSettings;

            //Old way of file reading. This leads to unexpected behavior when a user's FTP program transfers these files as ASCII (\r\n becomes \n).
            //var settings = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            var settings = new List<string>();
            using (var reader = new StringReader(text))
            {
                string str;
                while ((str = reader.ReadLine()) != null)
                    settings.Add(str);
            }

            foreach (var setting in settings)
            {
                var separatorIndex = setting.IndexOf(separator);
                if (separatorIndex == -1)
                {
                    continue;
                }
                string key = setting.Substring(0, separatorIndex).Trim();
                string value = setting.Substring(separatorIndex + 1).Trim();

                switch (key)
                {
                    case "DataProvider":
                        shellSettings.DataProvider = value;
                        break;
                    case "DataConnectionString":
                        shellSettings.DataConnectionString = value;
                        break;
                    default:
                        shellSettings.RawDataSettings.Add(key, value);
                        break;
                }
            }

            return shellSettings;
        }

        protected virtual string ComposeSettings(DataSettings settings)
        {
            if (settings == null)
                return "";

            return string.Format("DataProvider: {0}{2}DataConnectionString: {1}{2}",
                                 settings.DataProvider,
                                 settings.DataConnectionString,
                                 Environment.NewLine
                );
        }

        public virtual DataSettings LoadSettings()
        {
            string filePath = Path.GetFullPath(filename);
            if (File.Exists(filePath))
            {

                FileStream fsEncrypted = new FileStream(filePath,
                   FileMode.Open,
                   FileAccess.Read);

                byte[] key = new byte[8];

                fsEncrypted.Read(key, 0, 8);

                byte[] decrypted = new byte[1024];
                Stream s = new MemoryStream(decrypted);

                FileEncryptor.DecryptFile(fsEncrypted, s, key);
                fsEncrypted.Close();
                s.Close();

                string text = Encoding.ASCII.GetString(decrypted);
                return ParseSettings(text);
            }
            else
                return new DataSettings();
        }

        public virtual void SaveSettings(DataSettings settings)
        {
            if (settings == null)
                throw new ArgumentNullException("settings");

            //use webHelper.MapPath instead of HostingEnvironment.MapPath which is not available in unit tests
            string filePath = Path.GetFullPath(filename);
            if (!File.Exists(filePath))
            {
                using (File.Create(filePath))
                {
                    //we use 'using' to close the file after it's created
                }
            }

            var text = ComposeSettings(settings);
            File.WriteAllText(filePath, text);
        }
    }
}
